Browse Source

20200916, 万集雷达完全合并进入

huli 4 years ago
parent
commit
0022e164c3

+ 4 - 0
communication/communication_message.cpp

@@ -83,6 +83,10 @@ std::string& Communication_message::get_message_buf()
 	return m_message_buf;
 }
 
+std::chrono::system_clock::time_point Communication_message::get_receive_time()
+{
+	return m_receive_time;
+}
 
 
 

+ 1 - 0
communication/communication_message.h

@@ -61,6 +61,7 @@ public://get or set member variable
 	Communicator get_sender();
 	Communicator get_receiver();
 	std::string& get_message_buf();
+	std::chrono::system_clock::time_point get_receive_time();
 
 protected://member variable
 	Message_type								m_message_type;				//消息类型

+ 6 - 3
error_code/error_code.h

@@ -268,7 +268,9 @@ enum Error_code
     WJ_PROTOCOL_EXCEED_MAX_SIZE,
 
     //wj region detect error from 0x06030000-0x0603FFFF
-        WJ_REGION_EMPTY_CLOUD=0x06030000,
+	WJ_REGION_ERROR_BASE					= 0x06030000,
+	WJ_REGION_EMPTY_CLOUD,
+	WJ_REGION_EMPTY_NO_WHEEL_INFORMATION,
     WJ_REGION_RECTANGLE_ANGLE_ERROR,
     WJ_REGION_RECTANGLE_SIZE_ERROR,
     WJ_REGION_RECTANGLE_SYMMETRY_ERROR,
@@ -284,8 +286,9 @@ enum Error_code
 	WJ_MANAGER_TASK_TYPE_ERROR,									//万集管理模块,任务类型错误
 	WJ_MANAGER_STATUS_BUSY,										//万集管理模块,状态正忙
 	WJ_MANAGER_STATUS_ERROR,									//万集管理模块,状态错误
-	WJ_MANAGER_LASER_INDEX_ERRPR,				//雷达管理模块,雷达索引错误,编号错误。
-	WJ_MANAGER_LASER_INDEX_REPEAT,				//雷达管理模块,需要扫描的雷达索引重复,可忽略的错误,提示作用
+	WJ_MANAGER_LASER_INDEX_ERRPR,								//万集管理模块,雷达索引错误,编号错误。
+	WJ_MANAGER_LASER_INDEX_REPEAT,								//万集管理模块,需要扫描的雷达索引重复,可忽略的错误,提示作用
+	WJ_MANAGER_TASK_OVER_TIME,									//万集管理模块,任务超时
 
 
 	WJ_LIDAR_TASK_EMPTY_RESULT=0x06050000,

+ 2 - 2
main.cpp

@@ -69,7 +69,7 @@ int main(int argc,char* argv[])
 
 	Wanji_manager::get_instance_references().wanji_manager_init();
 	std::cout << " huli test :::: " << " wanji_manager_init = " << 1 << std::endl;
-
+/*
 	while (1  )
 	{
 		char ch1 ;
@@ -132,7 +132,7 @@ int main(int argc,char* argv[])
 	return 0;
 
 
-
+*/
 
 
 

File diff suppressed because it is too large
+ 526 - 137
message/measure_message.pb.cc


+ 389 - 77
message/measure_message.pb.h

@@ -159,6 +159,74 @@ inline bool Locate_manager_status_Parse(
   return ::google::protobuf::internal::ParseNamedEnum<Locate_manager_status>(
     Locate_manager_status_descriptor(), name, value);
 }
+enum Wanji_manager_status {
+  WANJI_MANAGER_UNKNOWN = 0,
+  WANJI_MANAGER_READY = 1,
+  WANJI_MANAGER_BUSY = 2,
+  WANJI_MANAGER_ISSUED_SCAN = 3,
+  WANJI_MANAGER_WAIT_SCAN = 4,
+  WANJI_MANAGER_ISSUED_DETECT = 5,
+  WANJI_MANAGER_WAIT_DETECT = 6,
+  WANJI_MANAGER_FAULT = 10
+};
+bool Wanji_manager_status_IsValid(int value);
+const Wanji_manager_status Wanji_manager_status_MIN = WANJI_MANAGER_UNKNOWN;
+const Wanji_manager_status Wanji_manager_status_MAX = WANJI_MANAGER_FAULT;
+const int Wanji_manager_status_ARRAYSIZE = Wanji_manager_status_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* Wanji_manager_status_descriptor();
+inline const ::std::string& Wanji_manager_status_Name(Wanji_manager_status value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Wanji_manager_status_descriptor(), value);
+}
+inline bool Wanji_manager_status_Parse(
+    const ::std::string& name, Wanji_manager_status* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Wanji_manager_status>(
+    Wanji_manager_status_descriptor(), name, value);
+}
+enum Wanji_lidar_device_status {
+  WANJI_LIDAR_DEVICE_UNKNOWN = 0,
+  WANJI_LIDAR_DEVICE_READY = 1,
+  WANJI_LIDAR_DEVICE_DISCONNECT = 2,
+  WANJI_LIDAR_DEVICE_BUSY = 3,
+  WANJI_LIDAR_DEVICE_FAULT = 10
+};
+bool Wanji_lidar_device_status_IsValid(int value);
+const Wanji_lidar_device_status Wanji_lidar_device_status_MIN = WANJI_LIDAR_DEVICE_UNKNOWN;
+const Wanji_lidar_device_status Wanji_lidar_device_status_MAX = WANJI_LIDAR_DEVICE_FAULT;
+const int Wanji_lidar_device_status_ARRAYSIZE = Wanji_lidar_device_status_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* Wanji_lidar_device_status_descriptor();
+inline const ::std::string& Wanji_lidar_device_status_Name(Wanji_lidar_device_status value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Wanji_lidar_device_status_descriptor(), value);
+}
+inline bool Wanji_lidar_device_status_Parse(
+    const ::std::string& name, Wanji_lidar_device_status* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Wanji_lidar_device_status>(
+    Wanji_lidar_device_status_descriptor(), name, value);
+}
+enum Region_worker_status {
+  REGION_WORKER_UNKNOWN = 0,
+  REGION_WORKER_READY = 1,
+  REGION_WORKER_BUSY = 2,
+  REGION_WORKER_FAULT = 10
+};
+bool Region_worker_status_IsValid(int value);
+const Region_worker_status Region_worker_status_MIN = REGION_WORKER_UNKNOWN;
+const Region_worker_status Region_worker_status_MAX = REGION_WORKER_FAULT;
+const int Region_worker_status_ARRAYSIZE = Region_worker_status_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* Region_worker_status_descriptor();
+inline const ::std::string& Region_worker_status_Name(Region_worker_status value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Region_worker_status_descriptor(), value);
+}
+inline bool Region_worker_status_Parse(
+    const ::std::string& name, Region_worker_status* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Region_worker_status>(
+    Region_worker_status_descriptor(), name, value);
+}
 // ===================================================================
 
 class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:message.Measure_status_msg) */ {
@@ -260,6 +328,38 @@ class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insert
   const ::google::protobuf::RepeatedField<int>& laser_statu_vector() const;
   ::google::protobuf::RepeatedField<int>* mutable_laser_statu_vector();
 
+  // repeated .message.Wanji_lidar_device_status wanji_lidar_device_status = 7;
+  int wanji_lidar_device_status_size() const;
+  void clear_wanji_lidar_device_status();
+  static const int kWanjiLidarDeviceStatusFieldNumber = 7;
+  ::message::Wanji_lidar_device_status wanji_lidar_device_status(int index) const;
+  void set_wanji_lidar_device_status(int index, ::message::Wanji_lidar_device_status value);
+  void add_wanji_lidar_device_status(::message::Wanji_lidar_device_status value);
+  const ::google::protobuf::RepeatedField<int>& wanji_lidar_device_status() const;
+  ::google::protobuf::RepeatedField<int>* mutable_wanji_lidar_device_status();
+
+  // repeated .message.Region_worker_status region_worker_status = 8;
+  int region_worker_status_size() const;
+  void clear_region_worker_status();
+  static const int kRegionWorkerStatusFieldNumber = 8;
+  ::message::Region_worker_status region_worker_status(int index) const;
+  void set_region_worker_status(int index, ::message::Region_worker_status value);
+  void add_region_worker_status(::message::Region_worker_status value);
+  const ::google::protobuf::RepeatedField<int>& region_worker_status() const;
+  ::google::protobuf::RepeatedField<int>* mutable_region_worker_status();
+
+  // repeated .message.Locate_information locate_information_realtime = 9;
+  int locate_information_realtime_size() const;
+  void clear_locate_information_realtime();
+  static const int kLocateInformationRealtimeFieldNumber = 9;
+  const ::message::Locate_information& locate_information_realtime(int index) const;
+  ::message::Locate_information* mutable_locate_information_realtime(int index);
+  ::message::Locate_information* add_locate_information_realtime();
+  ::google::protobuf::RepeatedPtrField< ::message::Locate_information >*
+      mutable_locate_information_realtime();
+  const ::google::protobuf::RepeatedPtrField< ::message::Locate_information >&
+      locate_information_realtime() const;
+
   // required .message.Base_info base_info = 1;
   bool has_base_info() const;
   void clear_base_info();
@@ -269,19 +369,10 @@ class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insert
   ::message::Base_info* mutable_base_info();
   void set_allocated_base_info(::message::Base_info* base_info);
 
-  // optional .message.Locate_information locate_information_realtime = 6;
-  bool has_locate_information_realtime() const;
-  void clear_locate_information_realtime();
-  static const int kLocateInformationRealtimeFieldNumber = 6;
-  const ::message::Locate_information& locate_information_realtime() const;
-  ::message::Locate_information* release_locate_information_realtime();
-  ::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 = 10;
   bool has_error_manager() const;
   void clear_error_manager();
-  static const int kErrorManagerFieldNumber = 7;
+  static const int kErrorManagerFieldNumber = 10;
   const ::message::Error_manager& error_manager() const;
   ::message::Error_manager* release_error_manager();
   ::message::Error_manager* mutable_error_manager();
@@ -308,6 +399,13 @@ class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insert
   ::message::Locate_manager_status locate_manager_status() const;
   void set_locate_manager_status(::message::Locate_manager_status value);
 
+  // required .message.Wanji_manager_status wanji_manager_status = 6;
+  bool has_wanji_manager_status() const;
+  void clear_wanji_manager_status();
+  static const int kWanjiManagerStatusFieldNumber = 6;
+  ::message::Wanji_manager_status wanji_manager_status() const;
+  void set_wanji_manager_status(::message::Wanji_manager_status value);
+
   // @@protoc_insertion_point(class_scope:message.Measure_status_msg)
  private:
   void set_has_base_info();
@@ -318,8 +416,8 @@ class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insert
   void clear_has_laser_manager_status();
   void set_has_locate_manager_status();
   void clear_has_locate_manager_status();
-  void set_has_locate_information_realtime();
-  void clear_has_locate_information_realtime();
+  void set_has_wanji_manager_status();
+  void clear_has_wanji_manager_status();
   void set_has_error_manager();
   void clear_has_error_manager();
 
@@ -330,12 +428,15 @@ class Measure_status_msg : public ::google::protobuf::Message /* @@protoc_insert
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable int _cached_size_;
   ::google::protobuf::RepeatedField<int> laser_statu_vector_;
+  ::google::protobuf::RepeatedField<int> wanji_lidar_device_status_;
+  ::google::protobuf::RepeatedField<int> region_worker_status_;
+  ::google::protobuf::RepeatedPtrField< ::message::Locate_information > locate_information_realtime_;
   ::message::Base_info* base_info_;
-  ::message::Locate_information* locate_information_realtime_;
   ::message::Error_manager* error_manager_;
   ::google::protobuf::int32 terminal_id_;
   int laser_manager_status_;
   int locate_manager_status_;
+  int wanji_manager_status_;
   friend struct ::protobuf_measure_5fmessage_2eproto::TableStruct;
   friend void ::protobuf_measure_5fmessage_2eproto::InitDefaultsMeasure_status_msgImpl();
 };
@@ -983,10 +1084,10 @@ class Locate_sift_request_msg : public ::google::protobuf::Message /* @@protoc_i
 
   // accessors -------------------------------------------------------
 
-  // repeated .message.Cloud_coordinate cloud_coordinates = 4;
+  // repeated .message.Cloud_coordinate cloud_coordinates = 5;
   int cloud_coordinates_size() const;
   void clear_cloud_coordinates();
-  static const int kCloudCoordinatesFieldNumber = 4;
+  static const int kCloudCoordinatesFieldNumber = 5;
   const ::message::Cloud_coordinate& cloud_coordinates(int index) const;
   ::message::Cloud_coordinate* mutable_cloud_coordinates(int index);
   ::message::Cloud_coordinate* add_cloud_coordinates();
@@ -1026,6 +1127,13 @@ class Locate_sift_request_msg : public ::google::protobuf::Message /* @@protoc_i
   ::google::protobuf::int32 terminal_id() const;
   void set_terminal_id(::google::protobuf::int32 value);
 
+  // required int32 lidar_id = 4;
+  bool has_lidar_id() const;
+  void clear_lidar_id();
+  static const int kLidarIdFieldNumber = 4;
+  ::google::protobuf::int32 lidar_id() const;
+  void set_lidar_id(::google::protobuf::int32 value);
+
   // @@protoc_insertion_point(class_scope:message.Locate_sift_request_msg)
  private:
   void set_has_base_info();
@@ -1034,6 +1142,8 @@ class Locate_sift_request_msg : public ::google::protobuf::Message /* @@protoc_i
   void clear_has_command_key();
   void set_has_terminal_id();
   void clear_has_terminal_id();
+  void set_has_lidar_id();
+  void clear_has_lidar_id();
 
   // helper for ByteSizeLong()
   size_t RequiredFieldsByteSizeFallback() const;
@@ -1045,6 +1155,7 @@ class Locate_sift_request_msg : public ::google::protobuf::Message /* @@protoc_i
   ::google::protobuf::internal::ArenaStringPtr command_key_;
   ::message::Base_info* base_info_;
   ::google::protobuf::int32 terminal_id_;
+  ::google::protobuf::int32 lidar_id_;
   friend struct ::protobuf_measure_5fmessage_2eproto::TableStruct;
   friend void ::protobuf_measure_5fmessage_2eproto::InitDefaultsLocate_sift_request_msgImpl();
 };
@@ -1139,10 +1250,10 @@ class Locate_sift_response_msg : public ::google::protobuf::Message /* @@protoc_
 
   // accessors -------------------------------------------------------
 
-  // repeated .message.Cloud_type cloud_type = 4;
+  // repeated .message.Cloud_type cloud_type = 5;
   int cloud_type_size() const;
   void clear_cloud_type();
-  static const int kCloudTypeFieldNumber = 4;
+  static const int kCloudTypeFieldNumber = 5;
   const ::message::Cloud_type& cloud_type(int index) const;
   ::message::Cloud_type* mutable_cloud_type(int index);
   ::message::Cloud_type* add_cloud_type();
@@ -1175,6 +1286,15 @@ class Locate_sift_response_msg : public ::google::protobuf::Message /* @@protoc_
   ::message::Base_info* mutable_base_info();
   void set_allocated_base_info(::message::Base_info* base_info);
 
+  // required .message.Error_manager error_manager = 6;
+  bool has_error_manager() const;
+  void clear_error_manager();
+  static const int kErrorManagerFieldNumber = 6;
+  const ::message::Error_manager& error_manager() const;
+  ::message::Error_manager* release_error_manager();
+  ::message::Error_manager* mutable_error_manager();
+  void set_allocated_error_manager(::message::Error_manager* error_manager);
+
   // required int32 terminal_id = 3;
   bool has_terminal_id() const;
   void clear_terminal_id();
@@ -1182,6 +1302,13 @@ class Locate_sift_response_msg : public ::google::protobuf::Message /* @@protoc_
   ::google::protobuf::int32 terminal_id() const;
   void set_terminal_id(::google::protobuf::int32 value);
 
+  // required int32 lidar_id = 4;
+  bool has_lidar_id() const;
+  void clear_lidar_id();
+  static const int kLidarIdFieldNumber = 4;
+  ::google::protobuf::int32 lidar_id() const;
+  void set_lidar_id(::google::protobuf::int32 value);
+
   // @@protoc_insertion_point(class_scope:message.Locate_sift_response_msg)
  private:
   void set_has_base_info();
@@ -1190,6 +1317,10 @@ class Locate_sift_response_msg : public ::google::protobuf::Message /* @@protoc_
   void clear_has_command_key();
   void set_has_terminal_id();
   void clear_has_terminal_id();
+  void set_has_lidar_id();
+  void clear_has_lidar_id();
+  void set_has_error_manager();
+  void clear_has_error_manager();
 
   // helper for ByteSizeLong()
   size_t RequiredFieldsByteSizeFallback() const;
@@ -1200,7 +1331,9 @@ class Locate_sift_response_msg : public ::google::protobuf::Message /* @@protoc_
   ::google::protobuf::RepeatedPtrField< ::message::Cloud_type > cloud_type_;
   ::google::protobuf::internal::ArenaStringPtr command_key_;
   ::message::Base_info* base_info_;
+  ::message::Error_manager* error_manager_;
   ::google::protobuf::int32 terminal_id_;
+  ::google::protobuf::int32 lidar_id_;
   friend struct ::protobuf_measure_5fmessage_2eproto::TableStruct;
   friend void ::protobuf_measure_5fmessage_2eproto::InitDefaultsLocate_sift_response_msgImpl();
 };
@@ -1267,13 +1400,13 @@ inline void Measure_status_msg::set_allocated_base_info(::message::Base_info* ba
 
 // required int32 terminal_id = 2;
 inline bool Measure_status_msg::has_terminal_id() const {
-  return (_has_bits_[0] & 0x00000008u) != 0;
+  return (_has_bits_[0] & 0x00000004u) != 0;
 }
 inline void Measure_status_msg::set_has_terminal_id() {
-  _has_bits_[0] |= 0x00000008u;
+  _has_bits_[0] |= 0x00000004u;
 }
 inline void Measure_status_msg::clear_has_terminal_id() {
-  _has_bits_[0] &= ~0x00000008u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline void Measure_status_msg::clear_terminal_id() {
   terminal_id_ = 0;
@@ -1291,13 +1424,13 @@ inline void Measure_status_msg::set_terminal_id(::google::protobuf::int32 value)
 
 // required .message.Laser_manager_status laser_manager_status = 3;
 inline bool Measure_status_msg::has_laser_manager_status() const {
-  return (_has_bits_[0] & 0x00000010u) != 0;
+  return (_has_bits_[0] & 0x00000008u) != 0;
 }
 inline void Measure_status_msg::set_has_laser_manager_status() {
-  _has_bits_[0] |= 0x00000010u;
+  _has_bits_[0] |= 0x00000008u;
 }
 inline void Measure_status_msg::clear_has_laser_manager_status() {
-  _has_bits_[0] &= ~0x00000010u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline void Measure_status_msg::clear_laser_manager_status() {
   laser_manager_status_ = 0;
@@ -1348,13 +1481,13 @@ Measure_status_msg::mutable_laser_statu_vector() {
 
 // required .message.Locate_manager_status locate_manager_status = 5;
 inline bool Measure_status_msg::has_locate_manager_status() const {
-  return (_has_bits_[0] & 0x00000020u) != 0;
+  return (_has_bits_[0] & 0x00000010u) != 0;
 }
 inline void Measure_status_msg::set_has_locate_manager_status() {
-  _has_bits_[0] |= 0x00000020u;
+  _has_bits_[0] |= 0x00000010u;
 }
 inline void Measure_status_msg::clear_has_locate_manager_status() {
-  _has_bits_[0] &= ~0x00000020u;
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline void Measure_status_msg::clear_locate_manager_status() {
   locate_manager_status_ = 0;
@@ -1371,65 +1504,131 @@ inline void Measure_status_msg::set_locate_manager_status(::message::Locate_mana
   // @@protoc_insertion_point(field_set:message.Measure_status_msg.locate_manager_status)
 }
 
-// optional .message.Locate_information locate_information_realtime = 6;
-inline bool Measure_status_msg::has_locate_information_realtime() const {
-  return (_has_bits_[0] & 0x00000002u) != 0;
+// required .message.Wanji_manager_status wanji_manager_status = 6;
+inline bool Measure_status_msg::has_wanji_manager_status() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void Measure_status_msg::set_has_locate_information_realtime() {
-  _has_bits_[0] |= 0x00000002u;
+inline void Measure_status_msg::set_has_wanji_manager_status() {
+  _has_bits_[0] |= 0x00000020u;
 }
-inline void Measure_status_msg::clear_has_locate_information_realtime() {
-  _has_bits_[0] &= ~0x00000002u;
+inline void Measure_status_msg::clear_has_wanji_manager_status() {
+  _has_bits_[0] &= ~0x00000020u;
 }
-inline const ::message::Locate_information& Measure_status_msg::locate_information_realtime() const {
-  const ::message::Locate_information* p = locate_information_realtime_;
-  // @@protoc_insertion_point(field_get:message.Measure_status_msg.locate_information_realtime)
-  return p != NULL ? *p : *reinterpret_cast<const ::message::Locate_information*>(
-      &::message::_Locate_information_default_instance_);
+inline void Measure_status_msg::clear_wanji_manager_status() {
+  wanji_manager_status_ = 0;
+  clear_has_wanji_manager_status();
 }
-inline ::message::Locate_information* Measure_status_msg::release_locate_information_realtime() {
-  // @@protoc_insertion_point(field_release:message.Measure_status_msg.locate_information_realtime)
-  clear_has_locate_information_realtime();
-  ::message::Locate_information* temp = locate_information_realtime_;
-  locate_information_realtime_ = NULL;
-  return temp;
+inline ::message::Wanji_manager_status Measure_status_msg::wanji_manager_status() const {
+  // @@protoc_insertion_point(field_get:message.Measure_status_msg.wanji_manager_status)
+  return static_cast< ::message::Wanji_manager_status >(wanji_manager_status_);
 }
-inline ::message::Locate_information* Measure_status_msg::mutable_locate_information_realtime() {
-  set_has_locate_information_realtime();
-  if (locate_information_realtime_ == NULL) {
-    locate_information_realtime_ = new ::message::Locate_information;
-  }
+inline void Measure_status_msg::set_wanji_manager_status(::message::Wanji_manager_status value) {
+  assert(::message::Wanji_manager_status_IsValid(value));
+  set_has_wanji_manager_status();
+  wanji_manager_status_ = value;
+  // @@protoc_insertion_point(field_set:message.Measure_status_msg.wanji_manager_status)
+}
+
+// repeated .message.Wanji_lidar_device_status wanji_lidar_device_status = 7;
+inline int Measure_status_msg::wanji_lidar_device_status_size() const {
+  return wanji_lidar_device_status_.size();
+}
+inline void Measure_status_msg::clear_wanji_lidar_device_status() {
+  wanji_lidar_device_status_.Clear();
+}
+inline ::message::Wanji_lidar_device_status Measure_status_msg::wanji_lidar_device_status(int index) const {
+  // @@protoc_insertion_point(field_get:message.Measure_status_msg.wanji_lidar_device_status)
+  return static_cast< ::message::Wanji_lidar_device_status >(wanji_lidar_device_status_.Get(index));
+}
+inline void Measure_status_msg::set_wanji_lidar_device_status(int index, ::message::Wanji_lidar_device_status value) {
+  assert(::message::Wanji_lidar_device_status_IsValid(value));
+  wanji_lidar_device_status_.Set(index, value);
+  // @@protoc_insertion_point(field_set:message.Measure_status_msg.wanji_lidar_device_status)
+}
+inline void Measure_status_msg::add_wanji_lidar_device_status(::message::Wanji_lidar_device_status value) {
+  assert(::message::Wanji_lidar_device_status_IsValid(value));
+  wanji_lidar_device_status_.Add(value);
+  // @@protoc_insertion_point(field_add:message.Measure_status_msg.wanji_lidar_device_status)
+}
+inline const ::google::protobuf::RepeatedField<int>&
+Measure_status_msg::wanji_lidar_device_status() const {
+  // @@protoc_insertion_point(field_list:message.Measure_status_msg.wanji_lidar_device_status)
+  return wanji_lidar_device_status_;
+}
+inline ::google::protobuf::RepeatedField<int>*
+Measure_status_msg::mutable_wanji_lidar_device_status() {
+  // @@protoc_insertion_point(field_mutable_list:message.Measure_status_msg.wanji_lidar_device_status)
+  return &wanji_lidar_device_status_;
+}
+
+// repeated .message.Region_worker_status region_worker_status = 8;
+inline int Measure_status_msg::region_worker_status_size() const {
+  return region_worker_status_.size();
+}
+inline void Measure_status_msg::clear_region_worker_status() {
+  region_worker_status_.Clear();
+}
+inline ::message::Region_worker_status Measure_status_msg::region_worker_status(int index) const {
+  // @@protoc_insertion_point(field_get:message.Measure_status_msg.region_worker_status)
+  return static_cast< ::message::Region_worker_status >(region_worker_status_.Get(index));
+}
+inline void Measure_status_msg::set_region_worker_status(int index, ::message::Region_worker_status value) {
+  assert(::message::Region_worker_status_IsValid(value));
+  region_worker_status_.Set(index, value);
+  // @@protoc_insertion_point(field_set:message.Measure_status_msg.region_worker_status)
+}
+inline void Measure_status_msg::add_region_worker_status(::message::Region_worker_status value) {
+  assert(::message::Region_worker_status_IsValid(value));
+  region_worker_status_.Add(value);
+  // @@protoc_insertion_point(field_add:message.Measure_status_msg.region_worker_status)
+}
+inline const ::google::protobuf::RepeatedField<int>&
+Measure_status_msg::region_worker_status() const {
+  // @@protoc_insertion_point(field_list:message.Measure_status_msg.region_worker_status)
+  return region_worker_status_;
+}
+inline ::google::protobuf::RepeatedField<int>*
+Measure_status_msg::mutable_region_worker_status() {
+  // @@protoc_insertion_point(field_mutable_list:message.Measure_status_msg.region_worker_status)
+  return &region_worker_status_;
+}
+
+// repeated .message.Locate_information locate_information_realtime = 9;
+inline int Measure_status_msg::locate_information_realtime_size() const {
+  return locate_information_realtime_.size();
+}
+inline const ::message::Locate_information& Measure_status_msg::locate_information_realtime(int index) const {
+  // @@protoc_insertion_point(field_get:message.Measure_status_msg.locate_information_realtime)
+  return locate_information_realtime_.Get(index);
+}
+inline ::message::Locate_information* Measure_status_msg::mutable_locate_information_realtime(int index) {
   // @@protoc_insertion_point(field_mutable:message.Measure_status_msg.locate_information_realtime)
-  return locate_information_realtime_;
+  return locate_information_realtime_.Mutable(index);
 }
-inline void Measure_status_msg::set_allocated_locate_information_realtime(::message::Locate_information* locate_information_realtime) {
-  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
-  if (message_arena == NULL) {
-    delete reinterpret_cast< ::google::protobuf::MessageLite*>(locate_information_realtime_);
-  }
-  if (locate_information_realtime) {
-    ::google::protobuf::Arena* submessage_arena = NULL;
-    if (message_arena != submessage_arena) {
-      locate_information_realtime = ::google::protobuf::internal::GetOwnedMessage(
-          message_arena, locate_information_realtime, submessage_arena);
-    }
-    set_has_locate_information_realtime();
-  } else {
-    clear_has_locate_information_realtime();
-  }
-  locate_information_realtime_ = locate_information_realtime;
-  // @@protoc_insertion_point(field_set_allocated:message.Measure_status_msg.locate_information_realtime)
+inline ::message::Locate_information* Measure_status_msg::add_locate_information_realtime() {
+  // @@protoc_insertion_point(field_add:message.Measure_status_msg.locate_information_realtime)
+  return locate_information_realtime_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::message::Locate_information >*
+Measure_status_msg::mutable_locate_information_realtime() {
+  // @@protoc_insertion_point(field_mutable_list:message.Measure_status_msg.locate_information_realtime)
+  return &locate_information_realtime_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::message::Locate_information >&
+Measure_status_msg::locate_information_realtime() const {
+  // @@protoc_insertion_point(field_list:message.Measure_status_msg.locate_information_realtime)
+  return locate_information_realtime_;
 }
 
-// required .message.Error_manager error_manager = 7;
+// required .message.Error_manager error_manager = 10;
 inline bool Measure_status_msg::has_error_manager() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000002u) != 0;
 }
 inline void Measure_status_msg::set_has_error_manager() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000002u;
 }
 inline void Measure_status_msg::clear_has_error_manager() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::message::Error_manager& Measure_status_msg::error_manager() const {
   const ::message::Error_manager* p = error_manager_;
@@ -2098,7 +2297,31 @@ inline void Locate_sift_request_msg::set_terminal_id(::google::protobuf::int32 v
   // @@protoc_insertion_point(field_set:message.Locate_sift_request_msg.terminal_id)
 }
 
-// repeated .message.Cloud_coordinate cloud_coordinates = 4;
+// required int32 lidar_id = 4;
+inline bool Locate_sift_request_msg::has_lidar_id() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void Locate_sift_request_msg::set_has_lidar_id() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void Locate_sift_request_msg::clear_has_lidar_id() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void Locate_sift_request_msg::clear_lidar_id() {
+  lidar_id_ = 0;
+  clear_has_lidar_id();
+}
+inline ::google::protobuf::int32 Locate_sift_request_msg::lidar_id() const {
+  // @@protoc_insertion_point(field_get:message.Locate_sift_request_msg.lidar_id)
+  return lidar_id_;
+}
+inline void Locate_sift_request_msg::set_lidar_id(::google::protobuf::int32 value) {
+  set_has_lidar_id();
+  lidar_id_ = value;
+  // @@protoc_insertion_point(field_set:message.Locate_sift_request_msg.lidar_id)
+}
+
+// repeated .message.Cloud_coordinate cloud_coordinates = 5;
 inline int Locate_sift_request_msg::cloud_coordinates_size() const {
   return cloud_coordinates_.size();
 }
@@ -2247,13 +2470,13 @@ inline void Locate_sift_response_msg::set_allocated_command_key(::std::string* c
 
 // required int32 terminal_id = 3;
 inline bool Locate_sift_response_msg::has_terminal_id() const {
-  return (_has_bits_[0] & 0x00000004u) != 0;
+  return (_has_bits_[0] & 0x00000008u) != 0;
 }
 inline void Locate_sift_response_msg::set_has_terminal_id() {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000008u;
 }
 inline void Locate_sift_response_msg::clear_has_terminal_id() {
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline void Locate_sift_response_msg::clear_terminal_id() {
   terminal_id_ = 0;
@@ -2269,7 +2492,31 @@ inline void Locate_sift_response_msg::set_terminal_id(::google::protobuf::int32
   // @@protoc_insertion_point(field_set:message.Locate_sift_response_msg.terminal_id)
 }
 
-// repeated .message.Cloud_type cloud_type = 4;
+// required int32 lidar_id = 4;
+inline bool Locate_sift_response_msg::has_lidar_id() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void Locate_sift_response_msg::set_has_lidar_id() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void Locate_sift_response_msg::clear_has_lidar_id() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void Locate_sift_response_msg::clear_lidar_id() {
+  lidar_id_ = 0;
+  clear_has_lidar_id();
+}
+inline ::google::protobuf::int32 Locate_sift_response_msg::lidar_id() const {
+  // @@protoc_insertion_point(field_get:message.Locate_sift_response_msg.lidar_id)
+  return lidar_id_;
+}
+inline void Locate_sift_response_msg::set_lidar_id(::google::protobuf::int32 value) {
+  set_has_lidar_id();
+  lidar_id_ = value;
+  // @@protoc_insertion_point(field_set:message.Locate_sift_response_msg.lidar_id)
+}
+
+// repeated .message.Cloud_type cloud_type = 5;
 inline int Locate_sift_response_msg::cloud_type_size() const {
   return cloud_type_.size();
 }
@@ -2299,6 +2546,56 @@ Locate_sift_response_msg::cloud_type() const {
   return cloud_type_;
 }
 
+// required .message.Error_manager error_manager = 6;
+inline bool Locate_sift_response_msg::has_error_manager() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void Locate_sift_response_msg::set_has_error_manager() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void Locate_sift_response_msg::clear_has_error_manager() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline const ::message::Error_manager& Locate_sift_response_msg::error_manager() const {
+  const ::message::Error_manager* p = error_manager_;
+  // @@protoc_insertion_point(field_get:message.Locate_sift_response_msg.error_manager)
+  return p != NULL ? *p : *reinterpret_cast<const ::message::Error_manager*>(
+      &::message::_Error_manager_default_instance_);
+}
+inline ::message::Error_manager* Locate_sift_response_msg::release_error_manager() {
+  // @@protoc_insertion_point(field_release:message.Locate_sift_response_msg.error_manager)
+  clear_has_error_manager();
+  ::message::Error_manager* temp = error_manager_;
+  error_manager_ = NULL;
+  return temp;
+}
+inline ::message::Error_manager* Locate_sift_response_msg::mutable_error_manager() {
+  set_has_error_manager();
+  if (error_manager_ == NULL) {
+    error_manager_ = new ::message::Error_manager;
+  }
+  // @@protoc_insertion_point(field_mutable:message.Locate_sift_response_msg.error_manager)
+  return error_manager_;
+}
+inline void Locate_sift_response_msg::set_allocated_error_manager(::message::Error_manager* error_manager) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == NULL) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(error_manager_);
+  }
+  if (error_manager) {
+    ::google::protobuf::Arena* submessage_arena = NULL;
+    if (message_arena != submessage_arena) {
+      error_manager = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, error_manager, submessage_arena);
+    }
+    set_has_error_manager();
+  } else {
+    clear_has_error_manager();
+  }
+  error_manager_ = error_manager;
+  // @@protoc_insertion_point(field_set_allocated:message.Locate_sift_response_msg.error_manager)
+}
+
 #ifdef __GNUC__
   #pragma GCC diagnostic pop
 #endif  // __GNUC__
@@ -2337,6 +2634,21 @@ template <>
 inline const EnumDescriptor* GetEnumDescriptor< ::message::Locate_manager_status>() {
   return ::message::Locate_manager_status_descriptor();
 }
+template <> struct is_proto_enum< ::message::Wanji_manager_status> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::message::Wanji_manager_status>() {
+  return ::message::Wanji_manager_status_descriptor();
+}
+template <> struct is_proto_enum< ::message::Wanji_lidar_device_status> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::message::Wanji_lidar_device_status>() {
+  return ::message::Wanji_lidar_device_status_descriptor();
+}
+template <> struct is_proto_enum< ::message::Region_worker_status> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::message::Region_worker_status>() {
+  return ::message::Region_worker_status_descriptor();
+}
 
 }  // namespace protobuf
 }  // namespace google

+ 51 - 8
message/measure_message.proto

@@ -32,18 +32,61 @@ enum Locate_manager_status
 	LOCATE_MANAGER_FAULT					= 5;	//故障
 }
 	
-	
+
+//雷达管理的状态
+enum Wanji_manager_status
+{
+	WANJI_MANAGER_UNKNOWN              	= 0;    //未知
+	WANJI_MANAGER_READY               	= 1;    //准备,待机
+	WANJI_MANAGER_BUSY					= 2; 	//工作正忙
+
+	WANJI_MANAGER_ISSUED_SCAN			= 3; 	//下发任务; 获取点云
+	WANJI_MANAGER_WAIT_SCAN				= 4;	//等待任务; 扫描点云
+
+	WANJI_MANAGER_ISSUED_DETECT			= 5; 	//下发任务; 算法预测
+	WANJI_MANAGER_WAIT_DETECT			= 6; 	//等待任务; 算法预测
+
+	WANJI_MANAGER_FAULT					= 10;	//故障
+}
+
+//万集设备身状态
+enum Wanji_lidar_device_status
+{
+	WANJI_LIDAR_DEVICE_UNKNOWN              	= 0;    //未知
+	WANJI_LIDAR_DEVICE_READY	             	= 1;    //正常待机
+	WANJI_LIDAR_DEVICE_DISCONNECT			= 2;	//断连
+
+	WANJI_LIDAR_DEVICE_BUSY					= 3; 	//工作正忙
+
+	WANJI_LIDAR_DEVICE_FAULT					=10;	//故障
+}
+
+//万集区域功能的状态
+enum Region_worker_status
+{
+	REGION_WORKER_UNKNOWN              	= 0;    //未知
+	REGION_WORKER_READY               	= 1;    //准备,待机
+	REGION_WORKER_BUSY					= 2; 	//工作正忙
+
+	REGION_WORKER_FAULT					= 10;	//故障
+}
+
 //定位模块状态
 message Measure_status_msg
 {
     required Base_info                  base_info=1;                 //消息类型
     required int32                      terminal_id=2;
-    required Laser_manager_status       laser_manager_status = 3;
-    repeated Laser_statu                laser_statu_vector = 4;
-    required Locate_manager_status      locate_manager_status = 5;
 
-    optional Locate_information         locate_information_realtime=6;  //地面雷达的 实时定位信息
-    required Error_manager              error_manager = 7;
+    required Laser_manager_status       laser_manager_status = 3;       //大疆管理状态
+    repeated Laser_statu                laser_statu_vector = 4;         //大疆雷达设备状态
+    required Locate_manager_status      locate_manager_status = 5;      //大疆定位算法状态
+
+    required Wanji_manager_status       wanji_manager_status = 6;       //万集管理状态
+    repeated Wanji_lidar_device_status  wanji_lidar_device_status = 7;  //万集设备身状态
+    repeated Region_worker_status       region_worker_status = 8;       //万集区域功能的状态
+    repeated Locate_information         locate_information_realtime = 9;//地面雷达的 实时定位信息
+
+    required Error_manager              error_manager = 10;
 }
 
 
@@ -79,7 +122,7 @@ message Cloud_type
     required int32                      type=1;
 }
 
-//筛选点云, 请求消息
+//筛选点云; 请求消息
 message Locate_sift_request_msg
 {
     required Base_info                  base_info=1;            //消息类型
@@ -89,7 +132,7 @@ message Locate_sift_request_msg
     repeated Cloud_coordinate           cloud_coordinates=5;     //点云坐标
 }
 
-//筛选点云, 答复消息
+//筛选点云; 答复消息
 message Locate_sift_response_msg
 {
     required Base_info                  base_info=1;            //消息类型

+ 116 - 70
message/message_base.pb.cc

@@ -229,6 +229,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Locate_information, locate_wheel_base_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Locate_information, locate_wheel_width_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Locate_information, locate_correct_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Locate_information, locate_front_theta_),
   0,
   1,
   2,
@@ -238,6 +239,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUT
   6,
   7,
   8,
+  9,
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Car_info, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::message::Car_info, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -283,9 +285,9 @@ static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROT
   { 0, 9, sizeof(::message::Base_info)},
   { 13, 19, sizeof(::message::Base_msg)},
   { 20, 28, sizeof(::message::Error_manager)},
-  { 31, 45, sizeof(::message::Locate_information)},
-  { 54, 63, sizeof(::message::Car_info)},
-  { 67, 83, sizeof(::message::Parkspace_info)},
+  { 31, 46, sizeof(::message::Locate_information)},
+  { 56, 65, sizeof(::message::Car_info)},
+  { 69, 85, sizeof(::message::Parkspace_info)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -327,69 +329,70 @@ void AddDescriptorsImpl() {
       "base_info\030\001 \002(\0132\022.message.Base_info\"i\n\rE"
       "rror_manager\022\022\n\nerror_code\030\001 \002(\005\022)\n\013erro"
       "r_level\030\002 \001(\0162\024.message.Error_level\022\031\n\021e"
-      "rror_description\030\003 \001(\t\"\341\001\n\022Locate_inform"
+      "rror_description\030\003 \001(\t\"\375\001\n\022Locate_inform"
       "ation\022\020\n\010locate_x\030\001 \001(\002\022\020\n\010locate_y\030\002 \001("
       "\002\022\024\n\014locate_angle\030\003 \001(\002\022\025\n\rlocate_length"
       "\030\004 \001(\002\022\024\n\014locate_width\030\005 \001(\002\022\025\n\rlocate_h"
       "eight\030\006 \001(\002\022\031\n\021locate_wheel_base\030\007 \001(\002\022\032"
       "\n\022locate_wheel_width\030\010 \001(\002\022\026\n\016locate_cor"
-      "rect\030\t \001(\010\"V\n\010Car_info\022\022\n\ncar_length\030\001 \001"
-      "(\002\022\021\n\tcar_width\030\002 \001(\002\022\022\n\ncar_height\030\003 \001("
-      "\002\022\017\n\007license\030\004 \001(\t\"\234\002\n\016Parkspace_info\022\024\n"
-      "\014parkspace_id\030\001 \001(\005\022\r\n\005index\030\002 \001(\005\022%\n\tdi"
-      "rection\030\003 \001(\0162\022.message.Direction\022\r\n\005flo"
-      "or\030\004 \001(\005\022\016\n\006length\030\005 \001(\002\022\r\n\005width\030\006 \001(\002\022"
-      "\016\n\006height\030\007 \001(\002\0223\n\020parkspace_status\030\010 \001("
-      "\0162\031.message.Parkspace_status\022#\n\010car_info"
-      "\030\t \001(\0132\021.message.Car_info\022\022\n\nentry_time\030"
-      "\n \001(\t\022\022\n\nleave_time\030\013 \001(\t*\253\007\n\014Message_ty"
-      "pe\022\r\n\teBase_msg\020\000\022\020\n\014eCommand_msg\020\001\022\026\n\022e"
-      "Locate_status_msg\020\021\022\027\n\023eLocate_request_m"
-      "sg\020\022\022\030\n\024eLocate_response_msg\020\023\022\030\n\024eDispa"
-      "tch_status_msg\020!\022\031\n\025eDispatch_request_ms"
-      "g\020\"\022\032\n\026eDispatch_response_msg\020#\022$\n ePark"
-      "space_allocation_status_msg\0201\022%\n!eParksp"
-      "ace_allocation_request_msg\0202\022&\n\"eParkspa"
-      "ce_allocation_response_msg\0203\022!\n\035eParkspa"
-      "ce_search_request_msg\0204\022\"\n\036eParkspace_se"
-      "arch_response_msg\0205\022\"\n\036eParkspace_releas"
-      "e_request_msg\0206\022#\n\037eParkspace_release_re"
-      "sponse_msg\0207\022\'\n#eParkspace_force_update_"
-      "request_msg\0208\022(\n$eParkspace_force_update"
-      "_response_msg\0209\022(\n$eParkspace_confirm_al"
-      "loc_request_msg\020:\022)\n%eParkspace_confirm_"
-      "alloc_response_msg\020;\022\036\n\032eStore_command_r"
-      "equest_msg\020A\022\037\n\033eStore_command_response_"
-      "msg\020B\022\037\n\033ePickup_command_request_msg\020C\022 "
-      "\n\034ePickup_command_response_msg\020D\022\037\n\032eSto"
-      "ring_process_statu_msg\020\220\001\022\037\n\032ePicking_pr"
-      "ocess_statu_msg\020\221\001\022\"\n\035eCentral_controlle"
-      "r_statu_msg\020\240\001\022#\n\036eEntrance_manual_opera"
-      "tion_msg\020\260\001\022\"\n\035eProcess_manual_operation"
-      "_msg\020\261\001*f\n\014Communicator\022\n\n\006eEmpty\020\000\022\t\n\005e"
-      "Main\020\001\022\016\n\teTerminor\020\200\002\022\017\n\neParkspace\020\200\004\022"
-      "\016\n\teMeasurer\020\200\006\022\016\n\teDispatch\020\200\010**\n\014Proce"
-      "ss_type\022\014\n\010eStoring\020\001\022\014\n\010ePicking\020\002*e\n\013E"
-      "rror_level\022\n\n\006NORMAL\020\000\022\024\n\020NEGLIGIBLE_ERR"
-      "OR\020\001\022\017\n\013MINOR_ERROR\020\002\022\017\n\013MAJOR_ERROR\020\003\022\022"
-      "\n\016CRITICAL_ERROR\020\004*q\n\020Parkspace_status\022\024"
-      "\n\020eParkspace_empty\020\000\022\027\n\023eParkspace_occup"
-      "ied\020\001\022\030\n\024eParkspace_reserverd\020\002\022\024\n\020ePark"
-      "space_error\020\003*(\n\tDirection\022\014\n\010eForward\020\001"
-      "\022\r\n\teBackward\020\002*\335\002\n\tStep_type\022\017\n\013eAlloc_"
-      "step\020\000\022\021\n\reMeasure_step\020\001\022\021\n\reCompare_st"
-      "ep\020\002\022\022\n\016eDispatch_step\020\003\022\021\n\reConfirm_ste"
-      "p\020\004\022\020\n\014eSearch_step\020\005\022\016\n\neWait_step\020\006\022\021\n"
-      "\reRelease_step\020\007\022\r\n\teComplete\020\010\022\025\n\021eBack"
-      "Confirm_step\020\t\022\026\n\022eBack_compare_step\020\n\022\025"
-      "\n\021eBackMeasure_step\020\013\022\023\n\017eBackAlloc_step"
-      "\020\014\022\022\n\016eBackWait_step\020\r\022\026\n\022eBackDispatch_"
-      "step\020\016\022\024\n\020eBackSearch_step\020\017\022\021\n\reBackCom"
-      "plete\020\020*C\n\nStep_statu\022\014\n\010eWaiting\020\000\022\014\n\010e"
-      "Working\020\001\022\n\n\006eError\020\002\022\r\n\teFinished\020\003"
+      "rect\030\t \001(\010\022\032\n\022locate_front_theta\030\n \001(\002\"V"
+      "\n\010Car_info\022\022\n\ncar_length\030\001 \001(\002\022\021\n\tcar_wi"
+      "dth\030\002 \001(\002\022\022\n\ncar_height\030\003 \001(\002\022\017\n\007license"
+      "\030\004 \001(\t\"\234\002\n\016Parkspace_info\022\024\n\014parkspace_i"
+      "d\030\001 \001(\005\022\r\n\005index\030\002 \001(\005\022%\n\tdirection\030\003 \001("
+      "\0162\022.message.Direction\022\r\n\005floor\030\004 \001(\005\022\016\n\006"
+      "length\030\005 \001(\002\022\r\n\005width\030\006 \001(\002\022\016\n\006height\030\007 "
+      "\001(\002\0223\n\020parkspace_status\030\010 \001(\0162\031.message."
+      "Parkspace_status\022#\n\010car_info\030\t \001(\0132\021.mes"
+      "sage.Car_info\022\022\n\nentry_time\030\n \001(\t\022\022\n\nlea"
+      "ve_time\030\013 \001(\t*\253\007\n\014Message_type\022\r\n\teBase_"
+      "msg\020\000\022\020\n\014eCommand_msg\020\001\022\026\n\022eLocate_statu"
+      "s_msg\020\021\022\027\n\023eLocate_request_msg\020\022\022\030\n\024eLoc"
+      "ate_response_msg\020\023\022\030\n\024eDispatch_status_m"
+      "sg\020!\022\031\n\025eDispatch_request_msg\020\"\022\032\n\026eDisp"
+      "atch_response_msg\020#\022$\n eParkspace_alloca"
+      "tion_status_msg\0201\022%\n!eParkspace_allocati"
+      "on_request_msg\0202\022&\n\"eParkspace_allocatio"
+      "n_response_msg\0203\022!\n\035eParkspace_search_re"
+      "quest_msg\0204\022\"\n\036eParkspace_search_respons"
+      "e_msg\0205\022\"\n\036eParkspace_release_request_ms"
+      "g\0206\022#\n\037eParkspace_release_response_msg\0207"
+      "\022\'\n#eParkspace_force_update_request_msg\020"
+      "8\022(\n$eParkspace_force_update_response_ms"
+      "g\0209\022(\n$eParkspace_confirm_alloc_request_"
+      "msg\020:\022)\n%eParkspace_confirm_alloc_respon"
+      "se_msg\020;\022\036\n\032eStore_command_request_msg\020A"
+      "\022\037\n\033eStore_command_response_msg\020B\022\037\n\033ePi"
+      "ckup_command_request_msg\020C\022 \n\034ePickup_co"
+      "mmand_response_msg\020D\022\037\n\032eStoring_process"
+      "_statu_msg\020\220\001\022\037\n\032ePicking_process_statu_"
+      "msg\020\221\001\022\"\n\035eCentral_controller_statu_msg\020"
+      "\240\001\022#\n\036eEntrance_manual_operation_msg\020\260\001\022"
+      "\"\n\035eProcess_manual_operation_msg\020\261\001*f\n\014C"
+      "ommunicator\022\n\n\006eEmpty\020\000\022\t\n\005eMain\020\001\022\016\n\teT"
+      "erminor\020\200\002\022\017\n\neParkspace\020\200\004\022\016\n\teMeasurer"
+      "\020\200\006\022\016\n\teDispatch\020\200\010**\n\014Process_type\022\014\n\010e"
+      "Storing\020\001\022\014\n\010ePicking\020\002*e\n\013Error_level\022\n"
+      "\n\006NORMAL\020\000\022\024\n\020NEGLIGIBLE_ERROR\020\001\022\017\n\013MINO"
+      "R_ERROR\020\002\022\017\n\013MAJOR_ERROR\020\003\022\022\n\016CRITICAL_E"
+      "RROR\020\004*q\n\020Parkspace_status\022\024\n\020eParkspace"
+      "_empty\020\000\022\027\n\023eParkspace_occupied\020\001\022\030\n\024ePa"
+      "rkspace_reserverd\020\002\022\024\n\020eParkspace_error\020"
+      "\003*(\n\tDirection\022\014\n\010eForward\020\001\022\r\n\teBackwar"
+      "d\020\002*\335\002\n\tStep_type\022\017\n\013eAlloc_step\020\000\022\021\n\reM"
+      "easure_step\020\001\022\021\n\reCompare_step\020\002\022\022\n\016eDis"
+      "patch_step\020\003\022\021\n\reConfirm_step\020\004\022\020\n\014eSear"
+      "ch_step\020\005\022\016\n\neWait_step\020\006\022\021\n\reRelease_st"
+      "ep\020\007\022\r\n\teComplete\020\010\022\025\n\021eBackConfirm_step"
+      "\020\t\022\026\n\022eBack_compare_step\020\n\022\025\n\021eBackMeasu"
+      "re_step\020\013\022\023\n\017eBackAlloc_step\020\014\022\022\n\016eBackW"
+      "ait_step\020\r\022\026\n\022eBackDispatch_step\020\016\022\024\n\020eB"
+      "ackSearch_step\020\017\022\021\n\reBackComplete\020\020*C\n\nS"
+      "tep_statu\022\014\n\010eWaiting\020\000\022\014\n\010eWorking\020\001\022\n\n"
+      "\006eError\020\002\022\r\n\teFinished\020\003"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 2716);
+      descriptor, 2744);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "message_base.proto", &protobuf_RegisterTypes);
 }
@@ -1610,6 +1613,7 @@ const int Locate_information::kLocateHeightFieldNumber;
 const int Locate_information::kLocateWheelBaseFieldNumber;
 const int Locate_information::kLocateWheelWidthFieldNumber;
 const int Locate_information::kLocateCorrectFieldNumber;
+const int Locate_information::kLocateFrontThetaFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Locate_information::Locate_information()
@@ -1627,16 +1631,16 @@ Locate_information::Locate_information(const Locate_information& from)
       _cached_size_(0) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   ::memcpy(&locate_x_, &from.locate_x_,
-    static_cast<size_t>(reinterpret_cast<char*>(&locate_correct_) -
-    reinterpret_cast<char*>(&locate_x_)) + sizeof(locate_correct_));
+    static_cast<size_t>(reinterpret_cast<char*>(&locate_front_theta_) -
+    reinterpret_cast<char*>(&locate_x_)) + sizeof(locate_front_theta_));
   // @@protoc_insertion_point(copy_constructor:message.Locate_information)
 }
 
 void Locate_information::SharedCtor() {
   _cached_size_ = 0;
   ::memset(&locate_x_, 0, static_cast<size_t>(
-      reinterpret_cast<char*>(&locate_correct_) -
-      reinterpret_cast<char*>(&locate_x_)) + sizeof(locate_correct_));
+      reinterpret_cast<char*>(&locate_front_theta_) -
+      reinterpret_cast<char*>(&locate_x_)) + sizeof(locate_front_theta_));
 }
 
 Locate_information::~Locate_information() {
@@ -1682,7 +1686,11 @@ void Locate_information::Clear() {
         reinterpret_cast<char*>(&locate_wheel_width_) -
         reinterpret_cast<char*>(&locate_x_)) + sizeof(locate_wheel_width_));
   }
-  locate_correct_ = false;
+  if (cached_has_bits & 768u) {
+    ::memset(&locate_correct_, 0, static_cast<size_t>(
+        reinterpret_cast<char*>(&locate_front_theta_) -
+        reinterpret_cast<char*>(&locate_correct_)) + sizeof(locate_front_theta_));
+  }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
 }
@@ -1823,6 +1831,20 @@ bool Locate_information::MergePartialFromCodedStream(
         break;
       }
 
+      // optional float locate_front_theta = 10;
+      case 10: {
+        if (static_cast< ::google::protobuf::uint8>(tag) ==
+            static_cast< ::google::protobuf::uint8>(85u /* 85 & 0xFF */)) {
+          set_has_locate_front_theta();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 input, &locate_front_theta_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
       default: {
       handle_unusual:
         if (tag == 0) {
@@ -1895,6 +1917,11 @@ void Locate_information::SerializeWithCachedSizes(
     ::google::protobuf::internal::WireFormatLite::WriteBool(9, this->locate_correct(), output);
   }
 
+  // optional float locate_front_theta = 10;
+  if (cached_has_bits & 0x00000200u) {
+    ::google::protobuf::internal::WireFormatLite::WriteFloat(10, this->locate_front_theta(), output);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         _internal_metadata_.unknown_fields(), output);
@@ -1955,6 +1982,11 @@ void Locate_information::SerializeWithCachedSizes(
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(9, this->locate_correct(), target);
   }
 
+  // optional float locate_front_theta = 10;
+  if (cached_has_bits & 0x00000200u) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(10, this->locate_front_theta(), target);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         _internal_metadata_.unknown_fields(), target);
@@ -2014,11 +2046,18 @@ size_t Locate_information::ByteSizeLong() const {
     }
 
   }
-  // optional bool locate_correct = 9;
-  if (has_locate_correct()) {
-    total_size += 1 + 1;
-  }
+  if (_has_bits_[8 / 32] & 768u) {
+    // optional bool locate_correct = 9;
+    if (has_locate_correct()) {
+      total_size += 1 + 1;
+    }
+
+    // optional float locate_front_theta = 10;
+    if (has_locate_front_theta()) {
+      total_size += 1 + 4;
+    }
 
+  }
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = cached_size;
@@ -2076,8 +2115,14 @@ void Locate_information::MergeFrom(const Locate_information& from) {
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  if (cached_has_bits & 0x00000100u) {
-    set_locate_correct(from.locate_correct());
+  if (cached_has_bits & 768u) {
+    if (cached_has_bits & 0x00000100u) {
+      locate_correct_ = from.locate_correct_;
+    }
+    if (cached_has_bits & 0x00000200u) {
+      locate_front_theta_ = from.locate_front_theta_;
+    }
+    _has_bits_[0] |= cached_has_bits;
   }
 }
 
@@ -2114,6 +2159,7 @@ void Locate_information::InternalSwap(Locate_information* other) {
   swap(locate_wheel_base_, other->locate_wheel_base_);
   swap(locate_wheel_width_, other->locate_wheel_width_);
   swap(locate_correct_, other->locate_correct_);
+  swap(locate_front_theta_, other->locate_front_theta_);
   swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   swap(_cached_size_, other->_cached_size_);

+ 34 - 0
message/message_base.pb.h

@@ -837,6 +837,13 @@ class Locate_information : public ::google::protobuf::Message /* @@protoc_insert
   bool locate_correct() const;
   void set_locate_correct(bool value);
 
+  // optional float locate_front_theta = 10;
+  bool has_locate_front_theta() const;
+  void clear_locate_front_theta();
+  static const int kLocateFrontThetaFieldNumber = 10;
+  float locate_front_theta() const;
+  void set_locate_front_theta(float value);
+
   // @@protoc_insertion_point(class_scope:message.Locate_information)
  private:
   void set_has_locate_x();
@@ -857,6 +864,8 @@ class Locate_information : public ::google::protobuf::Message /* @@protoc_insert
   void clear_has_locate_wheel_width();
   void set_has_locate_correct();
   void clear_has_locate_correct();
+  void set_has_locate_front_theta();
+  void clear_has_locate_front_theta();
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
@@ -870,6 +879,7 @@ class Locate_information : public ::google::protobuf::Message /* @@protoc_insert
   float locate_wheel_base_;
   float locate_wheel_width_;
   bool locate_correct_;
+  float locate_front_theta_;
   friend struct ::protobuf_message_5fbase_2eproto::TableStruct;
   friend void ::protobuf_message_5fbase_2eproto::InitDefaultsLocate_informationImpl();
 };
@@ -1753,6 +1763,30 @@ inline void Locate_information::set_locate_correct(bool value) {
   // @@protoc_insertion_point(field_set:message.Locate_information.locate_correct)
 }
 
+// optional float locate_front_theta = 10;
+inline bool Locate_information::has_locate_front_theta() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void Locate_information::set_has_locate_front_theta() {
+  _has_bits_[0] |= 0x00000200u;
+}
+inline void Locate_information::clear_has_locate_front_theta() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+inline void Locate_information::clear_locate_front_theta() {
+  locate_front_theta_ = 0;
+  clear_has_locate_front_theta();
+}
+inline float Locate_information::locate_front_theta() const {
+  // @@protoc_insertion_point(field_get:message.Locate_information.locate_front_theta)
+  return locate_front_theta_;
+}
+inline void Locate_information::set_locate_front_theta(float value) {
+  set_has_locate_front_theta();
+  locate_front_theta_ = value;
+  // @@protoc_insertion_point(field_set:message.Locate_information.locate_front_theta)
+}
+
 // -------------------------------------------------------------------
 
 // Car_info

+ 2 - 0
message/message_base.proto

@@ -123,6 +123,8 @@ message Locate_information
     optional float locate_wheel_base = 7;	    //整车的轮距; 前后轮的距离; 用于机器人或agv的抓车
     optional float locate_wheel_width = 8;	    //整车的轮距; 左右轮的距离; 用于机器人或agv的抓车
     optional bool locate_correct = 9;		    //整车的校准标记位
+
+    optional float locate_front_theta = 10;	    //整车的前轮的旋转角
 }
 
 //车辆基本信息

+ 10 - 2
setting/communication.prototxt

@@ -13,8 +13,16 @@ communication_parameters
  #  bind_string:"tcp://192.168.2.192:30001"
  #  bind_string:"tcp://192.168.2.167:30001"
 
-   connect_string_vector:"tcp://192.168.2.183:30002"
-   connect_string_vector:"tcp://192.168.2.125:7001"
+
+
+
+
+
+  # connect_string_vector:"tcp://192.168.2.183:30002"
+ #  connect_string_vector:"tcp://192.168.2.125:7001"
+
+
+   connect_string_vector:"tcp://192.168.2.233:2333"
 
 }
 

+ 205 - 36
system/system_executor.cpp

@@ -7,6 +7,8 @@
 #include "../laser/laser_manager.h"
 #include "../locate/locate_manager.h"
 #include "../system/system_communication.h"
+#include "../wanji_lidar/wanji_manager.h"
+#include "../tool/common_data.h"
 
 System_executor::System_executor()
 {
@@ -176,7 +178,8 @@ Error_manager System_executor::execute_msg(Communication_message* p_msg)
 			{
 				//往线程池添加执行任务, 之后会唤醒一个线程去执行他.
 				m_thread_pool.enqueue(&System_executor::execute_for_measure, this,
-									  t_measure_request_msg.command_key(), t_measure_request_msg.terminal_id());
+									  t_measure_request_msg.command_key(), t_measure_request_msg.terminal_id(),
+									  p_msg->get_receive_time());
 			}
 			else
 			{
@@ -222,10 +225,11 @@ Error_manager System_executor::encapsulate_send_status()
 	t_measure_status_msg.mutable_base_info()->set_msg_type(message::Message_type::eLocate_status_msg);
 	t_measure_status_msg.mutable_base_info()->set_timeout_ms(5000);
 	t_measure_status_msg.mutable_base_info()->set_sender(message::Communicator::eMeasurer);
-	t_measure_status_msg.mutable_base_info()->set_receiver(message::Communicator::eMain);
+	t_measure_status_msg.mutable_base_info()->set_receiver(message::Communicator::eEmpty);
 
 	t_measure_status_msg.set_terminal_id(m_terminal_id);
 
+	//大疆livox
 	Laser_manager::Laser_manager_status t_laser_manager_status = Laser_manager::get_instance_references().get_laser_manager_status();
 	t_measure_status_msg.set_laser_manager_status((message::Laser_manager_status)t_laser_manager_status);
 
@@ -239,19 +243,49 @@ Error_manager System_executor::encapsulate_send_status()
 	Locate_manager::Locate_manager_status t_locate_manager_status = Locate_manager::get_instance_references().get_locate_manager_status();
 	t_measure_status_msg.set_locate_manager_status((message::Locate_manager_status)t_locate_manager_status);
 
+	//万集716
+	Wanji_manager::Wanji_manager_status t_wanji_manager_status = Wanji_manager::get_instance_references().get_status();
+	t_measure_status_msg.set_wanji_manager_status((message::Wanji_manager_status)t_wanji_manager_status);
+
+	std::map<int, Wanji_lidar_device*> & t_wanji_lidar_device_map = Wanji_manager::get_instance_references().get_wanji_lidar_device_map();
+	for (auto iter = t_wanji_lidar_device_map.begin(); iter != t_wanji_lidar_device_map.end(); ++iter)
+	{
+		Wanji_lidar_device::Wanji_lidar_device_status t_wanji_lidar_device_status = (*iter).second->get_status();
+		t_measure_status_msg.add_wanji_lidar_device_status((message::Wanji_lidar_device_status)t_wanji_lidar_device_status);
+	}
+
+	std::map<int, Region_worker*> & t_region_worker_map = Wanji_manager::get_instance_references().get_region_worker_map();
+	for (auto iter = t_region_worker_map.begin(); iter != t_region_worker_map.end(); ++iter)
+	{
+		Region_worker::Region_worker_status t_region_worker_status = (*iter).second->get_status();
+		t_measure_status_msg.add_region_worker_status((message::Region_worker_status)t_region_worker_status);
+
+		//万集雷达的自动定位信息
+		Common_data::Car_wheel_information	t_car_wheel_information;
+		t_error = (*iter).second->get_last_wheel_information(&t_car_wheel_information, std::chrono::system_clock::now());
+
+		//无论定位结果如何, 都要填充数据, 即使全部写0, 必须保证通信格式正确.
+		message::Locate_information* tp_locate_information = t_measure_status_msg.add_locate_information_realtime();
+		tp_locate_information->set_locate_x(t_car_wheel_information.center_x);
+		tp_locate_information->set_locate_y(t_car_wheel_information.center_y);
+		tp_locate_information->set_locate_angle(t_car_wheel_information.car_angle);
+		tp_locate_information->set_locate_length(0);
+		tp_locate_information->set_locate_width(0);
+		tp_locate_information->set_locate_height(0);
+		tp_locate_information->set_locate_wheel_base(t_car_wheel_information.wheel_base);
+		tp_locate_information->set_locate_wheel_width(t_car_wheel_information.wheel_width);
+		tp_locate_information->set_locate_front_theta(t_car_wheel_information.front_theta);
+		tp_locate_information->set_locate_correct(t_car_wheel_information.correctness);
+	}
+
+
 	t_measure_status_msg.mutable_error_manager()->set_error_code(t_error.get_error_code());
 	t_measure_status_msg.mutable_error_manager()->set_error_level((message::Error_level)t_error.get_error_level());
 	t_measure_status_msg.mutable_error_manager()->set_error_description(t_error.get_error_description(), t_error.get_description_length());
 
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_x(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_y(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_angle(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_length(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_width(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_height(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_wheel_base(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_wheel_width(0);
-	t_measure_status_msg.mutable_locate_information_realtime()->set_locate_correct(0);
+	std::cout << " huli test :::: " << " t_measure_status_msg.DebugString() = "  << std::endl;
+	std::cout << t_measure_status_msg.DebugString() << std::endl;
+
 
 	string t_msg = t_measure_status_msg.SerializeAsString();
 	System_communication::get_instance_references().encapsulate_msg(t_msg);
@@ -284,12 +318,12 @@ System_executor::System_executor_status System_executor::get_system_executor_sta
 //input::command_id, 消息指令id, 由主控制系统生成的唯一码
 //input::command_id, 终端id, 对应具体的某个车位
 //return::void, 没有返回, 执行结果直接生成一条答复消息, 然后通过通信返回
-void System_executor::execute_for_measure(std::string command_info, int terminal_id)
+void System_executor::execute_for_measure(std::string command_info, int terminal_id,std::chrono::system_clock::time_point receive_time)
 {
 	Error_manager t_error;
-
+	Error_manager t_result;
 	LOG(INFO) << " System_executor::execute_for_measure run "<< this;
-/*
+
 	//第一步, 创建点云缓存, 和 指定雷达,目前就一个
 	std::map<int,pcl::PointCloud<pcl::PointXYZ>::Ptr>		point_cloud_map;
 	std::mutex cloud_lock;
@@ -345,19 +379,25 @@ void System_executor::execute_for_measure(std::string command_info, int terminal
 
 		//提取任务单 的错误码
 		t_error = laser_manager_task.get_task_error_manager();
-		std::cout << "huli laser_manager_task error :::::::"  << laser_manager_task.get_task_error_manager().to_string() << std::endl;
+		if ( t_error != Error_code::SUCCESS )
+		{
+			LOG(INFO) << " laser_manager_task error :::::::"  << laser_manager_task.get_task_error_manager().to_string() << this;
+		}
 	}
+	t_result.compare_and_cover_error(t_error);
+
 
 
 	Locate_manager_task locate_manager_task ;
-	//第五步, 创建定位模块的任务单, 并发送到 Locate_manager
+	Common_data::Car_measure_information t_car_information_by_livox;
+
 	if ( t_error != Error_code::SUCCESS )
 	{
 	    LOG(INFO) << " laser_manager_task error "<< this;
 	}
 	else
 	{
-
+		//第五步, 创建定位模块的任务单, 并发送到 Locate_manager
 		locate_manager_task.task_init(TASK_CREATED,"",NULL,std::chrono::milliseconds(15000),
 									   true,t_save_path,&cloud_lock,&point_cloud_map, false	);
 		t_error = Task_command_manager::get_instance_references().execute_task(&locate_manager_task);
@@ -391,9 +431,136 @@ void System_executor::execute_for_measure(std::string command_info, int terminal
 			}
 			//提取任务单 的错误码
 			t_error = locate_manager_task.get_task_error_manager();
-			std::cout << "huli locate_manager_task error :::::::"  << locate_manager_task.get_task_error_manager().to_string() << std::endl;
+			if ( t_error == Error_code::SUCCESS )
+			{
+				t_car_information_by_livox.center_x = locate_manager_task.get_task_locate_information_ex()->locate_x;
+				t_car_information_by_livox.center_y = locate_manager_task.get_task_locate_information_ex()->locate_y;
+				t_car_information_by_livox.car_angle = locate_manager_task.get_task_locate_information_ex()->locate_angle;
+				t_car_information_by_livox.car_length = locate_manager_task.get_task_locate_information_ex()->locate_length;
+				t_car_information_by_livox.car_width = locate_manager_task.get_task_locate_information_ex()->locate_width;
+				t_car_information_by_livox.car_height = locate_manager_task.get_task_locate_information_ex()->locate_height;
+				t_car_information_by_livox.wheel_base = locate_manager_task.get_task_locate_information_ex()->locate_wheel_base;
+				t_car_information_by_livox.wheel_width = locate_manager_task.get_task_locate_information_ex()->locate_wheel_width;
+				t_car_information_by_livox.front_theta = 0;
+				t_car_information_by_livox.correctness = true;
+			}
+			else
+			{
+			    LOG(INFO) << " locate_manager_task error :::::::"  << locate_manager_task.get_task_error_manager().to_string() << this;
+			}
+		}
+	}
+	t_result.compare_and_cover_error(t_error);
+
+
+	//第7步, 创建万集管理模块的任务单, 并发送到 wanji_manager
+	Wanji_manager_task  t_wanji_manager_task ;
+	Common_data::Car_wheel_information	t_car_information_by_wanji;
+	t_wanji_manager_task.task_init(TASK_CREATED,"",NULL,std::chrono::milliseconds(15000),
+								   terminal_id, receive_time);
+	t_error = Task_command_manager::get_instance_references().execute_task(&t_wanji_manager_task);
+
+
+	//第8步, 等待任务单完成
+	if ( t_error != Error_code::SUCCESS )
+	{
+		LOG(INFO) << " Wanji_manager  execute_task   error "<< this;
+	}
+	else
+	{
+		//判断任务是否结束, 阻塞 等待, 直到任务完成或者超时
+		while ( t_wanji_manager_task.is_task_end() == false)
+		{
+			if ( t_wanji_manager_task.is_over_time() )
+			{
+				//超时处理。取消任务。
+				Wanji_manager::get_instance_pointer()->cancel_task(&t_wanji_manager_task);
+				t_error.error_manager_reset(Error_code::WJ_MANAGER_TASK_OVER_TIME, Error_level::MINOR_ERROR,
+											" t_wanji_manager_task is_over_time ");
+				t_wanji_manager_task.set_task_error_manager(t_error);
+			}
+			else
+			{
+				//继续等待
+				std::this_thread::sleep_for(std::chrono::microseconds(1));
+				std::this_thread::yield();
+			}
+		}
+
+		//提取任务单 的错误码
+		t_error = t_wanji_manager_task.get_task_error_manager();
+		if ( t_error == Error_code::SUCCESS )
+		{
+			t_car_information_by_wanji = t_wanji_manager_task.get_car_wheel_information();
+		}
+		else
+		{
+		    LOG(INFO) << " wanji_manager_task error :::::::"  << t_wanji_manager_task.get_task_error_manager().to_string() << this;
+		}
+	}
+	t_result.compare_and_cover_error(t_error);
+
+
+	//measure 测量模块的最终结果
+	Common_data::Car_measure_information	t_car_information_result;
+	//第9步, 对比livox和万集的, 并且进行校验
+	//都成功则选最优解, 返回成功
+	//其中一个构成, 就返回一个数据, 并返回错误码, 降级为一级故障
+	//都失败就直接返回错误码,
+	if ( t_car_information_by_livox.correctness == true && t_car_information_by_wanji.correctness == true )
+	{
+		//2个都有效时, 进行对比
+		float offset_x = fabs(t_car_information_by_livox.center_x - t_car_information_by_wanji.center_x);
+		float offset_y = fabs(t_car_information_by_livox.center_y - t_car_information_by_wanji.center_y);
+		float offset_angle = fabs(t_car_information_by_livox.car_angle - t_car_information_by_wanji.car_angle);
+		float offset_wheel_width = fabs(t_car_information_by_livox.wheel_width - t_car_information_by_wanji.wheel_width);
+		float offset_wheel_base = fabs(t_car_information_by_livox.wheel_base - t_car_information_by_wanji.wheel_base);
+		if (offset_x > 100 || offset_y > 150 || offset_angle > 3 || offset_wheel_base > 550 || offset_wheel_width > 250) {
+			LOG(WARNING) << "chekc failed. (offset x>100, y>150, angle>3, wheel_base>550, width>250): " << offset_x
+						 << " " << offset_y << " " << offset_angle << " " << offset_wheel_base << " " << offset_wheel_width;
+			t_error =  Error_manager(TERMINOR_CHECK_RESULTS_ERROR, MINOR_ERROR, "check results failed ");
+			t_result.compare_and_cover_error(t_error);
+		}
+		else
+		{
+			///根据sigmod函数计算角度权重
+			double angle_weight=1.0-1.0/(1.0+exp(-offset_angle/1.8));
+			///根据两个结果选择最优结果,中心点选择万集雷达,角度选择两值加权,轴距已以2750为基准作卡尔曼滤波
+			///车长以大疆雷达为准,车宽以万集雷达为准,高以大疆雷达为准
+			t_car_information_result.center_x = t_car_information_by_wanji.center_x;
+			t_car_information_result.center_y = t_car_information_by_wanji.center_y;
+
+			t_car_information_result.car_angle =angle_weight * t_car_information_by_wanji.car_angle +
+												(1.0-angle_weight) * t_car_information_by_livox.car_angle;
+
+			t_car_information_result.car_length = t_car_information_by_livox.car_length;
+			t_car_information_result.car_width = t_car_information_by_livox.car_width;
+			t_car_information_result.car_height = t_car_information_by_livox.car_height;
+
+			float dj_distance = fabs(t_car_information_by_livox.wheel_base - 2750);
+			float wj_distance = fabs(t_car_information_by_wanji.wheel_base - 2750);
+			float weight_dj = wj_distance / (dj_distance + wj_distance);
+			float weight_wj = dj_distance / (dj_distance + wj_distance);
+			t_car_information_result.wheel_base = weight_dj * t_car_information_by_livox.wheel_base +
+													  weight_wj * t_car_information_by_wanji.wheel_base;
+			t_car_information_result.wheel_base=t_car_information_result.wheel_base>3000?3000:t_car_information_result.wheel_base;
+
+			t_car_information_result.wheel_width = t_car_information_by_wanji.wheel_width;
+			t_car_information_result.correctness = true;
 		}
 	}
+	else if( t_car_information_by_livox.correctness == true && t_car_information_by_wanji.correctness == false )
+	{
+		t_car_information_result = t_car_information_by_livox;
+		t_result.set_error_level_down(NEGLIGIBLE_ERROR);
+	}
+	else if( t_car_information_by_livox.correctness == false && t_car_information_by_wanji.correctness == true )
+	{
+		Common_data::copy_data(t_car_information_by_wanji, t_car_information_result);
+		t_result.set_error_level_down(NEGLIGIBLE_ERROR);
+	}
+
+
 
 	//第七步, 创建一条答复消息
 	message::Measure_response_msg t_measure_response_msg;
@@ -402,24 +569,23 @@ void System_executor::execute_for_measure(std::string command_info, int terminal
 	t_measure_response_msg.mutable_base_info()->set_sender(message::Communicator::eMeasurer);
 	t_measure_response_msg.mutable_base_info()->set_receiver(message::Communicator::eMain);
 
-	t_measure_response_msg.set_command_id(command_id);
+	t_measure_response_msg.set_command_key(command_info);
 	t_measure_response_msg.set_terminal_id(terminal_id);
-	t_measure_response_msg.mutable_error_manager()->set_error_code(t_error.get_error_code());
-	t_measure_response_msg.mutable_error_manager()->set_error_level((message::Error_level)t_error.get_error_level());
-	t_measure_response_msg.mutable_error_manager()->set_error_description(t_error.get_error_description(), t_error.get_description_length());
+	t_measure_response_msg.mutable_error_manager()->set_error_code(t_result.get_error_code());
+	t_measure_response_msg.mutable_error_manager()->set_error_level((message::Error_level)t_result.get_error_level());
+	t_measure_response_msg.mutable_error_manager()->set_error_description(t_result.get_error_description(), t_result.get_description_length());
+
+	t_measure_response_msg.mutable_locate_information()->set_locate_x(t_car_information_result.center_x);
+	t_measure_response_msg.mutable_locate_information()->set_locate_y(t_car_information_result.center_y);
+	t_measure_response_msg.mutable_locate_information()->set_locate_angle(t_car_information_result.car_angle);
+	t_measure_response_msg.mutable_locate_information()->set_locate_length(t_car_information_result.car_length);
+	t_measure_response_msg.mutable_locate_information()->set_locate_width(t_car_information_result.car_width);
+	t_measure_response_msg.mutable_locate_information()->set_locate_height(t_car_information_result.car_height);
+	t_measure_response_msg.mutable_locate_information()->set_locate_wheel_base(t_car_information_result.wheel_base);
+	t_measure_response_msg.mutable_locate_information()->set_locate_wheel_width(t_car_information_result.wheel_width);
+	t_measure_response_msg.mutable_locate_information()->set_locate_front_theta(t_car_information_result.front_theta);
+	t_measure_response_msg.mutable_locate_information()->set_locate_correct(t_car_information_result.correctness);
 
-	if ( t_error == Error_code::SUCCESS )
-	{
-		t_measure_response_msg.mutable_locate_information()->set_locate_x(locate_manager_task.get_task_locate_information_ex()->locate_x);
-		t_measure_response_msg.mutable_locate_information()->set_locate_y(locate_manager_task.get_task_locate_information_ex()->locate_y);
-		t_measure_response_msg.mutable_locate_information()->set_locate_angle(locate_manager_task.get_task_locate_information_ex()->locate_angle);
-		t_measure_response_msg.mutable_locate_information()->set_locate_length(locate_manager_task.get_task_locate_information_ex()->locate_length);
-		t_measure_response_msg.mutable_locate_information()->set_locate_width(locate_manager_task.get_task_locate_information_ex()->locate_width);
-		t_measure_response_msg.mutable_locate_information()->set_locate_height(locate_manager_task.get_task_locate_information_ex()->locate_height);
-		t_measure_response_msg.mutable_locate_information()->set_locate_wheel_base(locate_manager_task.get_task_locate_information_ex()->locate_wheel_base);
-		t_measure_response_msg.mutable_locate_information()->set_locate_wheel_width(locate_manager_task.get_task_locate_information_ex()->locate_wheel_width);
-		t_measure_response_msg.mutable_locate_information()->set_locate_correct(locate_manager_task.get_task_locate_information_ex()->locate_correct);
-	}
 
 	string t_msg = t_measure_response_msg.SerializeAsString();
 	System_communication::get_instance_references().encapsulate_msg(t_msg);
@@ -428,11 +594,14 @@ void System_executor::execute_for_measure(std::string command_info, int terminal
 
 
 	return ;
-*/
 
 
 
 
+
+
+
+/*
 	message::Measure_response_msg t_measure_response_msg;
 	t_measure_response_msg.mutable_base_info()->set_msg_type(message::Message_type::eLocate_response_msg);
 	t_measure_response_msg.mutable_base_info()->set_timeout_ms(5000);
@@ -462,7 +631,7 @@ void System_executor::execute_for_measure(std::string command_info, int terminal
 	System_communication::get_instance_references().encapsulate_msg(t_msg);
 
 	std::cout << "huli t_measure_response_msg = " << t_measure_response_msg.DebugString() << std::endl;
-
+*/
 
 	return ;
 }

+ 1 - 1
system/system_executor.h

@@ -64,7 +64,7 @@ public:
 //input::command_id, 消息指令id, 由主控制系统生成的唯一码
 //input::command_id, 终端id, 对应具体的某个车位
 //return::void, 没有返回, 执行结果直接生成一条答复消息, 然后通过通信返回
-	void execute_for_measure(std::string command_info, int terminal_id);
+	void execute_for_measure(std::string command_info, int terminal_id,std::chrono::system_clock::time_point receive_time);
 
 
 protected://member variable

+ 9 - 2
task/task_command_manager.cpp

@@ -5,7 +5,7 @@
 #include "../laser/Laser.h"
 #include "../laser/laser_manager.h"
 #include "../locate/locate_manager.h"
-
+#include "../wanji_lidar/wanji_manager.h"
 //对外的接口函数,所有的任务发送方,都必须使用该函数。
 //execute_task在内部解析了Task_Base里面的Task_type,然后转发给具体某个模块的实例对象。
 //input:p_task_base 任务单,基类的指针,指向子类的实例,(多态)
@@ -54,7 +54,14 @@ Error_manager Task_command_manager::execute_task(Task_Base* p_task_base)
 			;
 			break;
 		case WANJI_MANAGER_TASK:
-			;
+			if ( tp_tast_receiver != NULL )
+			{
+				t_error = ((Wanji_manager*)tp_tast_receiver)->execute_task(p_task_base);
+			}
+			else
+			{
+				t_error = Wanji_manager::get_instance_references().execute_task(p_task_base);
+			}
 			break;
 	    default:
 			t_error.error_manager_reset(Error_code::TASK_TYPE_IS_UNKNOW, Error_level::MINOR_ERROR,

+ 402 - 398
wanji_lidar/region_detect.cpp

@@ -31,42 +31,42 @@ Error_manager Region_detector::init(Point2D_tool::Point2D_box point2D_box)
  * */
 Error_manager Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud)
 {
-    // 1.参数合法性检验
-    if (p_cloud->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-std::cout << " huli test :::: " << " 222 = " << 222 << std::endl;
-    // 2.直通滤波, 筛选xy
-    pcl::PassThrough<pcl::PointXYZ> pass;
-    pass.setInputCloud(p_cloud);
-    pass.setFilterFieldName("x");                                       //设置想在哪个坐标轴上操作
-    pass.setFilterLimits(m_region_box.x_min, m_region_box.x_max); //将x轴的0到1范围内
-    pass.setFilterLimitsNegative(false);                                //保留(true就是删除,false就是保留而删除此区间外的)
-    pass.filter(*p_cloud);                                            //输出到结果指针
-std::cout << " huli test :::: " << " 333 = " << 333 << std::endl;
-    if (p_cloud->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
-    pass.setInputCloud(p_cloud);
-    pass.setFilterFieldName("y");                                       //设置想在哪个坐标轴上操作
-    pass.setFilterLimits(m_region_box.y_min, m_region_box.y_max); //将x轴的0到1范围内
-    pass.setFilterLimitsNegative(false);                                //保留(true就是删除,false就是保留而删除此区间外的)
-    pass.filter(*p_cloud);                                            //输出到结果指针
-std::cout << " huli test :::: " << " 444 = " << 444 << std::endl;
-    if (p_cloud->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-std::cout << " huli test :::: " << " 445 = " << 445 << std::endl;
-    // 3.离群点过滤
-    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
-    sor.setInputCloud(p_cloud);
-    sor.setMeanK(15);            //K近邻搜索点个数
-    sor.setStddevMulThresh(3.0); //标准差倍数
-    sor.setNegative(false);      //保留未滤波点(内点)
-    sor.filter(*p_cloud);      //保存滤波结果到cloud_filter
-std::cout << " huli test :::: " << " 555 = " << 555 << std::endl;
-    if (p_cloud->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-    else
-        return Error_manager(Error_code::SUCCESS);
+	// 1.参数合法性检验
+	if (p_cloud->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+	std::cout << " huli test :::: " << " 222 = " << 222 << std::endl;
+	// 2.直通滤波, 筛选xy
+	pcl::PassThrough<pcl::PointXYZ> pass;
+	pass.setInputCloud(p_cloud);
+	pass.setFilterFieldName("x");                                       //设置想在哪个坐标轴上操作
+	pass.setFilterLimits(m_region_box.x_min, m_region_box.x_max); //将x轴的0到1范围内
+	pass.setFilterLimitsNegative(false);                                //保留(true就是删除,false就是保留而删除此区间外的)
+	pass.filter(*p_cloud);                                            //输出到结果指针
+	std::cout << " huli test :::: " << " 333 = " << 333 << std::endl;
+	if (p_cloud->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+
+	pass.setInputCloud(p_cloud);
+	pass.setFilterFieldName("y");                                       //设置想在哪个坐标轴上操作
+	pass.setFilterLimits(m_region_box.y_min, m_region_box.y_max); //将x轴的0到1范围内
+	pass.setFilterLimitsNegative(false);                                //保留(true就是删除,false就是保留而删除此区间外的)
+	pass.filter(*p_cloud);                                            //输出到结果指针
+	std::cout << " huli test :::: " << " 444 = " << 444 << std::endl;
+	if (p_cloud->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+	std::cout << " huli test :::: " << " 445 = " << 445 << std::endl;
+	// 3.离群点过滤
+	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
+	sor.setInputCloud(p_cloud);
+	sor.setMeanK(15);            //K近邻搜索点个数
+	sor.setStddevMulThresh(3.0); //标准差倍数
+	sor.setNegative(false);      //保留未滤波点(内点)
+	sor.filter(*p_cloud);      //保存滤波结果到cloud_filter
+	std::cout << " huli test :::: " << " 555 = " << 555 << std::endl;
+	if (p_cloud->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+	else
+		return Error_manager(Error_code::SUCCESS);
 }
 
 /**
@@ -74,7 +74,7 @@ std::cout << " huli test :::: " << " 555 = " << 555 << std::endl;
  * */
 double distance(cv::Point2f p1, cv::Point2f p2)
 {
-    return sqrt(pow(p1.x - p2.x, 2.0) + pow(p1.y - p2.y, 2.0));
+	return sqrt(pow(p1.x - p2.x, 2.0) + pow(p1.y - p2.y, 2.0));
 }
 
 /**
@@ -85,204 +85,204 @@ double distance(cv::Point2f p1, cv::Point2f p2)
  * */
 Error_manager Region_detector::isRect(std::vector<cv::Point2f> &points, bool print)
 {
-    if (points.size() == 4)
-    {
-        double L[3] = {0.0};
-        L[0] = distance(points[0], points[1]);
-        L[1] = distance(points[1], points[2]);
-        L[2] = distance(points[0], points[2]);
-        double max_l = L[0];
-        double l1 = L[1];
-        double l2 = L[2];
-        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)
-            {
-                max_index = i;
-                max_l = L[i];
-                l1 = L[abs(i + 1) % 3];
-                l2 = L[abs(i + 2) % 3];
-                ps = points[i % 3];
-                pt = points[(i + 1) % 3];
-                pc = points[(i + 2) % 3];
-            }
-        }
-        // 顶角大小
-        double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
-        // 顶角相对于90度过大或小
-        if (fabs(cosa) >= 0.15 /* || std::min(l1, l2) > 2.0 || std::max(l1, l2) > 3.3*/)
-        {
-            if (print)
-            {
-                LOG(WARNING) << " angle cos >0.13 =" << cosa << "  i=" << max_index;
-                // LOG(WARNING) << "L1:" << l1 << "  L2:" << l2 << "  L3:" << max_l;
-            }
-            return Error_manager(Error_code::WJ_REGION_RECTANGLE_ANGLE_ERROR);
-        }
-
-        float width = std::min(l1, l2);
-        float length = std::max(l1, l2);
-        // 车宽应位于[1.35, 2.0],车长应位于[2.2, 3.0]
-        if (width < 1.350 || width > 2.000 || length > 3.000 || length < 2.200)
-        {
-            if (print)
-            {
-                LOG(WARNING) << "\t width<1350 || width >2100 || length >3300 ||length < 2100 "
-                             << "  length:" << length << "  width:" << width;
-            }
-            return Error_manager(Error_code::WJ_REGION_RECTANGLE_SIZE_ERROR);
-        }
-
-        double d = distance(pc, points[3]);
-        cv::Point2f center1 = (ps + pt) * 0.5;
-        cv::Point2f center2 = (pc + points[3]) * 0.5;
-        // 对角线形变超过0.15倍,或中心点距离偏差0.15m
-        if (fabs(d - max_l) > max_l * 0.15 || distance(center1, center2) > 0.150)
-        {
-            if (print)
-            {
-                LOG(WARNING) << "d:" << d << " maxl:" << max_l << "  center1:" << center1 << "  center2:" << center2
-                             << "  center distance=" << distance(center1, center2);
-            }
-            return Error_manager(Error_code::WJ_REGION_RECTANGLE_SYMMETRY_ERROR);
-        }
-        if (print)
-        {
-            LOG(INFO) << " rectangle verify OK  cos angle=" << cosa << "  length off=" << fabs(d - max_l)
-                         << "  center distance=" << distance(center1, center2);
-        }
-        return Error_manager(Error_code::SUCCESS);
-    }
-    // 以三个点进行验证
-    else if (points.size() == 3)
-    {
-        double L[3] = {0.0};
-        L[0] = distance(points[0], points[1]);
-        L[1] = distance(points[1], points[2]);
-        L[2] = distance(points[0], points[2]);
-        double max_l = L[0];
-        double l1 = L[1];
-        double l2 = L[2];
-        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)
-            {
-                max_index = i;
-                max_l = L[i];
-                l1 = L[abs(i + 1) % 3];
-                l2 = L[abs(i + 2) % 3];
-                ps = points[i % 3];
-                pt = points[(i + 1) % 3];
-                pc = points[(i + 2) % 3];
-            }
-        }
-        double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
-        // 顶角应接近90度
-        if (fabs(cosa) >= 0.15)
-        {
-            if (print)
-            {
-                LOG(WARNING) << "3 wheels angle cos >0.12 =" << cosa << "  i=" << max_index;
-                LOG(WARNING) << "L1:" << l1 << "  L2:" << l2 << "  L3:" << max_l;
-            }
-            return Error_manager(Error_code::WJ_REGION_RECTANGLE_ANGLE_ERROR);
-        }
-
-        double length = std::max(l1, l2);
-        double width = std::min(l1, l2);
-        // 车宽应位于[1.4, 2.0],车长应位于[2.2, 3.0]
-        if (length > 2.100 && length < 3.000 && width > 1.400 && width < 2.100)
-        {
-            //生成第四个点
-            cv::Point2f vec1 = ps - pc;
-            cv::Point2f vec2 = pt - pc;
-            cv::Point2f point4 = (vec1 + vec2) + pc;
-            points.push_back(point4);
-            if (print)
-            {
-                LOG(WARNING) << "3 wheels rectangle verify OK  cos angle=" << cosa << "  L=" << length
-                             << "  w=" << width;
-            }
-            return Error_manager(Error_code::SUCCESS);
-        }
-        else
-        {
-            if (print)
-            {
-                LOG(WARNING) << "3 wheels rectangle verify Failed  cos angle=" << cosa << "  L=" << length
-                             << "  w=" << width;
-            }
-            return Error_manager(Error_code::WJ_REGION_RECTANGLE_SIZE_ERROR);
-        }
-    }
-    else
-    {
-        return Error_manager(Error_code::WJ_REGION_CLUSTER_SIZE_ERROR);
-    }
+	if (points.size() == 4)
+	{
+		double L[3] = {0.0};
+		L[0] = distance(points[0], points[1]);
+		L[1] = distance(points[1], points[2]);
+		L[2] = distance(points[0], points[2]);
+		double max_l = L[0];
+		double l1 = L[1];
+		double l2 = L[2];
+		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)
+			{
+				max_index = i;
+				max_l = L[i];
+				l1 = L[abs(i + 1) % 3];
+				l2 = L[abs(i + 2) % 3];
+				ps = points[i % 3];
+				pt = points[(i + 1) % 3];
+				pc = points[(i + 2) % 3];
+			}
+		}
+		// 顶角大小
+		double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
+		// 顶角相对于90度过大或小
+		if (fabs(cosa) >= 0.15 /* || std::min(l1, l2) > 2.0 || std::max(l1, l2) > 3.3*/)
+		{
+			if (print)
+			{
+				LOG(WARNING) << " angle cos >0.13 =" << cosa << "  i=" << max_index;
+				// LOG(WARNING) << "L1:" << l1 << "  L2:" << l2 << "  L3:" << max_l;
+			}
+			return Error_manager(Error_code::WJ_REGION_RECTANGLE_ANGLE_ERROR);
+		}
+
+		float width = std::min(l1, l2);
+		float length = std::max(l1, l2);
+		// 车宽应位于[1.35, 2.0],车长应位于[2.2, 3.0]
+		if (width < 1.350 || width > 2.000 || length > 3.000 || length < 2.200)
+		{
+			if (print)
+			{
+				LOG(WARNING) << "\t width<1350 || width >2100 || length >3300 ||length < 2100 "
+							 << "  length:" << length << "  width:" << width;
+			}
+			return Error_manager(Error_code::WJ_REGION_RECTANGLE_SIZE_ERROR);
+		}
+
+		double d = distance(pc, points[3]);
+		cv::Point2f center1 = (ps + pt) * 0.5;
+		cv::Point2f center2 = (pc + points[3]) * 0.5;
+		// 对角线形变超过0.15倍,或中心点距离偏差0.15m
+		if (fabs(d - max_l) > max_l * 0.15 || distance(center1, center2) > 0.150)
+		{
+			if (print)
+			{
+				LOG(WARNING) << "d:" << d << " maxl:" << max_l << "  center1:" << center1 << "  center2:" << center2
+							 << "  center distance=" << distance(center1, center2);
+			}
+			return Error_manager(Error_code::WJ_REGION_RECTANGLE_SYMMETRY_ERROR);
+		}
+		if (print)
+		{
+			LOG(INFO) << " rectangle verify OK  cos angle=" << cosa << "  length off=" << fabs(d - max_l)
+					  << "  center distance=" << distance(center1, center2);
+		}
+		return Error_manager(Error_code::SUCCESS);
+	}
+		// 以三个点进行验证
+	else if (points.size() == 3)
+	{
+		double L[3] = {0.0};
+		L[0] = distance(points[0], points[1]);
+		L[1] = distance(points[1], points[2]);
+		L[2] = distance(points[0], points[2]);
+		double max_l = L[0];
+		double l1 = L[1];
+		double l2 = L[2];
+		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)
+			{
+				max_index = i;
+				max_l = L[i];
+				l1 = L[abs(i + 1) % 3];
+				l2 = L[abs(i + 2) % 3];
+				ps = points[i % 3];
+				pt = points[(i + 1) % 3];
+				pc = points[(i + 2) % 3];
+			}
+		}
+		double cosa = (l1 * l1 + l2 * l2 - max_l * max_l) / (2.0 * l1 * l2);
+		// 顶角应接近90度
+		if (fabs(cosa) >= 0.15)
+		{
+			if (print)
+			{
+				LOG(WARNING) << "3 wheels angle cos >0.12 =" << cosa << "  i=" << max_index;
+				LOG(WARNING) << "L1:" << l1 << "  L2:" << l2 << "  L3:" << max_l;
+			}
+			return Error_manager(Error_code::WJ_REGION_RECTANGLE_ANGLE_ERROR);
+		}
+
+		double length = std::max(l1, l2);
+		double width = std::min(l1, l2);
+		// 车宽应位于[1.4, 2.0],车长应位于[2.2, 3.0]
+		if (length > 2.100 && length < 3.000 && width > 1.400 && width < 2.100)
+		{
+			//生成第四个点
+			cv::Point2f vec1 = ps - pc;
+			cv::Point2f vec2 = pt - pc;
+			cv::Point2f point4 = (vec1 + vec2) + pc;
+			points.push_back(point4);
+			if (print)
+			{
+				LOG(WARNING) << "3 wheels rectangle verify OK  cos angle=" << cosa << "  L=" << length
+							 << "  w=" << width;
+			}
+			return Error_manager(Error_code::SUCCESS);
+		}
+		else
+		{
+			if (print)
+			{
+				LOG(WARNING) << "3 wheels rectangle verify Failed  cos angle=" << cosa << "  L=" << length
+							 << "  w=" << width;
+			}
+			return Error_manager(Error_code::WJ_REGION_RECTANGLE_SIZE_ERROR);
+		}
+	}
+	else
+	{
+		return Error_manager(Error_code::WJ_REGION_CLUSTER_SIZE_ERROR);
+	}
 }
 
 /*
  * 仅仅聚类
  */
 Error_manager Region_detector::clustering_only(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
-        std::vector<pcl::PointCloud<pcl::PointXYZ>> &seg_clouds, bool print)
+											   std::vector<pcl::PointCloud<pcl::PointXYZ>> &seg_clouds, bool print)
 {
-    // 1.判断参数合法性
-    if (cloud_in->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
-    // 2.聚类
-    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
-    kdtree->setInputCloud(cloud_in);
-
-    pcl::EuclideanClusterExtraction<pcl::PointXYZ> clustering;
-    // 设置聚类的最小值 2cm (small values may cause objects to be divided
-    // in several clusters, whereas big values may join objects in a same cluster).
-    clustering.setClusterTolerance(0.5);
-    // 设置聚类的小点数和最大点云数
-    clustering.setMinClusterSize(10);
-    clustering.setMaxClusterSize(500);
-    clustering.setSearchMethod(kdtree);
-    clustering.setInputCloud(cloud_in);
-    std::vector<pcl::PointIndices> clusters;
-    clustering.extract(clusters);
-    if(clusters.size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
-    for (int i = 0; i < clusters.size(); ++i)
-    {
-        seg_clouds.push_back(pcl::PointCloud<pcl::PointXYZ>());
-    }
-
-    int j = 0;
-    for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
-    {
-        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
-        //创建新的点云数据集cloud_cluster,将所有当前聚类写入到点云数据集中
-        for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
-        {
-            cloud_cluster->points.push_back(cloud_in->points[*pit]);
-            cloud_cluster->width = cloud_cluster->points.size();
-            cloud_cluster->height = 1;
-            cloud_cluster->is_dense = true;
-        }
-        seg_clouds[j] = *cloud_cluster;
-        j++;
-    }
-
-    if (print)
-    {
-        LOG(INFO) << " cluster classes:" << clusters.size();
-    }
-
-    return SUCCESS;
+	// 1.判断参数合法性
+	if (cloud_in->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+
+	// 2.聚类
+	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
+	kdtree->setInputCloud(cloud_in);
+
+	pcl::EuclideanClusterExtraction<pcl::PointXYZ> clustering;
+	// 设置聚类的最小值 2cm (small values may cause objects to be divided
+	// in several clusters, whereas big values may join objects in a same cluster).
+	clustering.setClusterTolerance(0.5);
+	// 设置聚类的小点数和最大点云数
+	clustering.setMinClusterSize(10);
+	clustering.setMaxClusterSize(500);
+	clustering.setSearchMethod(kdtree);
+	clustering.setInputCloud(cloud_in);
+	std::vector<pcl::PointIndices> clusters;
+	clustering.extract(clusters);
+	if(clusters.size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+
+	for (int i = 0; i < clusters.size(); ++i)
+	{
+		seg_clouds.push_back(pcl::PointCloud<pcl::PointXYZ>());
+	}
+
+	int j = 0;
+	for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
+	{
+		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
+		//创建新的点云数据集cloud_cluster,将所有当前聚类写入到点云数据集中
+		for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
+		{
+			cloud_cluster->points.push_back(cloud_in->points[*pit]);
+			cloud_cluster->width = cloud_cluster->points.size();
+			cloud_cluster->height = 1;
+			cloud_cluster->is_dense = true;
+		}
+		seg_clouds[j] = *cloud_cluster;
+		j++;
+	}
+
+	if (print)
+	{
+		LOG(INFO) << " cluster classes:" << clusters.size();
+	}
+
+	return SUCCESS;
 }
 
 
@@ -294,80 +294,80 @@ Error_manager Region_detector::clustering_only(pcl::PointCloud<pcl::PointXYZ>::P
  * */
 Error_manager Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, std::vector<cv::Point2f> &corner_points, std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> &seg_clouds, bool print)
 {
-    // 1.判断参数合法性
-    if (cloud_in->size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
-    // 2.聚类
-    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
-    kdtree->setInputCloud(cloud_in);
-
-    pcl::EuclideanClusterExtraction<pcl::PointXYZ> clustering;
-    // 设置聚类的最小值 2cm (small values may cause objects to be divided
-    // in several clusters, whereas big values may join objects in a same cluster).
-    clustering.setClusterTolerance(0.2);
-    // 设置聚类的小点数和最大点云数
-    clustering.setMinClusterSize(10);
-    clustering.setMaxClusterSize(500);
-    clustering.setSearchMethod(kdtree);
-    clustering.setInputCloud(cloud_in);
-    std::vector<pcl::PointIndices> clusters;
-    clustering.extract(clusters);
-    if(clusters.size() <= 0)
-        return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
-    for (int i = 0; i < clusters.size(); ++i)
-    {
-        seg_clouds.push_back(pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>));
-    }
-
-    int j = 0;
-    for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
-    {
-        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
-        //创建新的点云数据集cloud_cluster,将所有当前聚类写入到点云数据集中
-        for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
-        {
-            cloud_cluster->points.push_back(cloud_in->points[*pit]);
-            cloud_cluster->width = cloud_cluster->points.size();
-            cloud_cluster->height = 1;
-            cloud_cluster->is_dense = true;
-        }
-        seg_clouds[j] = cloud_cluster;
-        j++;
-    }
-
-    if (print)
-    {
-        LOG(INFO) << " cluster classes:" << clusters.size();
-    }
-
-    // 3.分别计算每团点云几何中心,作为矩形角点
-    corner_points.clear();
-    for (int i = 0; i < clusters.size(); ++i)
-    {
-        if (seg_clouds.size() <= i || seg_clouds[i]->size() == 0)
-            continue;
-        float sumX = 0, sumY = 0;
-        for (int j = 0; j < seg_clouds[i]->size(); ++j)
-        {
-            sumX += seg_clouds[i]->points[j].x;
-            sumY += seg_clouds[i]->points[j].y;
-        }
-
-        float center_x = sumX / float(seg_clouds[i]->size());
-        float center_y = sumY / float(seg_clouds[i]->size());
-        corner_points.push_back(cv::Point2f(center_x, center_y));
-    }
-    /*char buf[255]={0};
-    for (int k = 0; k < corner_points.size(); ++k) {
-        sprintf(buf+strlen(buf), "point %d: (%.2f, %.2f)__", k, corner_points[k].x, corner_points[k].y);
-    }
-    LOG(WARNING) << buf;*/
-
-    cv::RotatedRect t_rect=cv::minAreaRect(corner_points);
-    //display(t_rect,cv::Scalar(255,0,0));
-    return isRect(corner_points, print);
+	// 1.判断参数合法性
+	if (cloud_in->size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+
+	// 2.聚类
+	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
+	kdtree->setInputCloud(cloud_in);
+
+	pcl::EuclideanClusterExtraction<pcl::PointXYZ> clustering;
+	// 设置聚类的最小值 2cm (small values may cause objects to be divided
+	// in several clusters, whereas big values may join objects in a same cluster).
+	clustering.setClusterTolerance(0.2);
+	// 设置聚类的小点数和最大点云数
+	clustering.setMinClusterSize(10);
+	clustering.setMaxClusterSize(500);
+	clustering.setSearchMethod(kdtree);
+	clustering.setInputCloud(cloud_in);
+	std::vector<pcl::PointIndices> clusters;
+	clustering.extract(clusters);
+	if(clusters.size() <= 0)
+		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+
+	for (int i = 0; i < clusters.size(); ++i)
+	{
+		seg_clouds.push_back(pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>));
+	}
+
+	int j = 0;
+	for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
+	{
+		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
+		//创建新的点云数据集cloud_cluster,将所有当前聚类写入到点云数据集中
+		for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
+		{
+			cloud_cluster->points.push_back(cloud_in->points[*pit]);
+			cloud_cluster->width = cloud_cluster->points.size();
+			cloud_cluster->height = 1;
+			cloud_cluster->is_dense = true;
+		}
+		seg_clouds[j] = cloud_cluster;
+		j++;
+	}
+
+	if (print)
+	{
+		LOG(INFO) << " cluster classes:" << clusters.size();
+	}
+
+	// 3.分别计算每团点云几何中心,作为矩形角点
+	corner_points.clear();
+	for (int i = 0; i < clusters.size(); ++i)
+	{
+		if (seg_clouds.size() <= i || seg_clouds[i]->size() == 0)
+			continue;
+		float sumX = 0, sumY = 0;
+		for (int j = 0; j < seg_clouds[i]->size(); ++j)
+		{
+			sumX += seg_clouds[i]->points[j].x;
+			sumY += seg_clouds[i]->points[j].y;
+		}
+
+		float center_x = sumX / float(seg_clouds[i]->size());
+		float center_y = sumY / float(seg_clouds[i]->size());
+		corner_points.push_back(cv::Point2f(center_x, center_y));
+	}
+	/*char buf[255]={0};
+	for (int k = 0; k < corner_points.size(); ++k) {
+		sprintf(buf+strlen(buf), "point %d: (%.2f, %.2f)__", k, corner_points[k].x, corner_points[k].y);
+	}
+	LOG(WARNING) << buf;*/
+
+	cv::RotatedRect t_rect=cv::minAreaRect(corner_points);
+	//display(t_rect,cv::Scalar(255,0,0));
+	return isRect(corner_points, print);
 }
 
 
@@ -375,24 +375,24 @@ Error_manager Region_detector::clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr cl
 
 // 检测传入点云,识别为四类返回中心点、角度、轮距与宽度
 Error_manager Region_detector::detect(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in,
-Common_data::Car_wheel_information& car_wheel_information, bool print)
+									  Common_data::Car_wheel_information& car_wheel_information, bool print)
 {
 	//整个函数都加锁, 这里面非法修改了输入点云, 是为了将筛选点云的结构传出, 然后点云存txt文件
 	std::unique_lock<std::mutex> t_lock(*p_cloud_mutex);
 	Error_manager result = Error_manager(Error_code::SUCCESS);
-    pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
+	pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
 	*p_cloud_filtered = *p_cloud_in;
 
-    // 1.预处理
-    result = preprocess(p_cloud_filtered);
-    if (result != SUCCESS)
-        return result;
+	// 1.预处理
+	result = preprocess(p_cloud_filtered);
+	if (result != SUCCESS)
+		return result;
 
-    // 2.聚类计算角点
-    std::vector<cv::Point2f> corner_points;
-    std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> seg_clouds;
-    result = clustering(p_cloud_filtered, corner_points, seg_clouds, print);
-    if (result != SUCCESS)
+	// 2.聚类计算角点
+	std::vector<cv::Point2f> corner_points;
+	std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> seg_clouds;
+	result = clustering(p_cloud_filtered, corner_points, seg_clouds, print);
+	if (result != SUCCESS)
 		return result;
 	// 修改原始点云为预处理后点云,并加入角点供查验
 
@@ -407,89 +407,89 @@ Common_data::Car_wheel_information& car_wheel_information, bool print)
 	std::vector<cv::Point2f> all_points;
 	// car center
 	for (int j = 0; j < p_cloud_filtered->size(); ++j)
-    {
-        all_points.push_back(cv::Point2f(p_cloud_filtered->points[j].x, p_cloud_filtered->points[j].y));
-    }
-    // find bounding rectangle of all wheel points
-    cv::RotatedRect wheel_box = cv::minAreaRect(all_points);
+	{
+		all_points.push_back(cv::Point2f(p_cloud_filtered->points[j].x, p_cloud_filtered->points[j].y));
+	}
+	// find bounding rectangle of all wheel points
+	cv::RotatedRect wheel_box = cv::minAreaRect(all_points);
 	car_wheel_information.center_x = wheel_box.center.x;
 	car_wheel_information.center_y = wheel_box.center.y;
-    // add center point to the input cloud for further check
+	// add center point to the input cloud for further check
 	p_cloud_in->points.push_back(pcl::PointXYZ(car_wheel_information.center_x, car_wheel_information.center_y, 0.0));
 
 
 
-    // 长边向量
-    cv::Point2f vec;
-    cv::Point2f vertice[4];
-    wheel_box.points(vertice);
-
-    float len1 = pow(vertice[0].x - vertice[1].x, 2.0) + pow(vertice[0].y - vertice[1].y, 2.0);
-    float len2 = pow(vertice[1].x - vertice[2].x, 2.0) + pow(vertice[1].y - vertice[2].y, 2.0);
-    // 寻找长边,倾角为长边与x轴夹角
-    if (len1 > len2)
-    {
-        vec.x = vertice[0].x - vertice[1].x;
-        vec.y = vertice[0].y - vertice[1].y;
-    }
-    else
-    {
-        vec.x = vertice[1].x - vertice[2].x;
-        vec.y = vertice[1].y - vertice[2].y;
-    }
-    float angle_x = 180.0 / M_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
+	// 长边向量
+	cv::Point2f vec;
+	cv::Point2f vertice[4];
+	wheel_box.points(vertice);
+
+	float len1 = pow(vertice[0].x - vertice[1].x, 2.0) + pow(vertice[0].y - vertice[1].y, 2.0);
+	float len2 = pow(vertice[1].x - vertice[2].x, 2.0) + pow(vertice[1].y - vertice[2].y, 2.0);
+	// 寻找长边,倾角为长边与x轴夹角
+	if (len1 > len2)
+	{
+		vec.x = vertice[0].x - vertice[1].x;
+		vec.y = vertice[0].y - vertice[1].y;
+	}
+	else
+	{
+		vec.x = vertice[1].x - vertice[2].x;
+		vec.y = vertice[1].y - vertice[2].y;
+	}
+	float angle_x = 180.0 / M_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
 	car_wheel_information.car_angle = angle_x;
 
-    // get line formula, normal is (cos(theta), sin(theta)), towards the long side
-    // the line formula is: nx * x + ny * y + (-(nx*cx+ny*cy)) = 0
-    Eigen::Vector2f normal, center_point;
-    normal << vec.x / sqrt(vec.x * vec.x + vec.y * vec.y), vec.y / sqrt(vec.x * vec.x + vec.y * vec.y);
-    center_point << car_wheel_information.center_x, car_wheel_information.center_y;
-    float line_param_c = -1 * center_point.transpose() * normal;
-    // get rotation matrix, get the angle towards normal vector, rather than x axis
-    // R = [ cos -sin]
-    //     [ sin  cos]
-    float rotate_angle = M_PI_2 - acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
-    Eigen::Matrix2f rotation_matrix;
-    rotation_matrix << cos(rotate_angle), -sin(rotate_angle), sin(rotate_angle), cos(rotate_angle);
-
-    // find min x and max x, separate y values according to the line, calculate difference between mean of y values as wheelbase
-    float min_x = 20, max_x = 0;
-    float y_values0 = 0, y_values1 = 0;
-    int count0 = 0, count1 = 0;
-    for (size_t i = 0; i < seg_clouds.size(); i++)
-    {
-        if (seg_clouds[i]->size() <= 0)
-            continue;
-        for (size_t j = 0; j < seg_clouds[i]->size(); j++)
-        {
-            // origin point and the point rotated around the origin
-            Eigen::Vector2f vec, vec_rot;
-            vec << seg_clouds[i]->points[j].x, seg_clouds[i]->points[j].y;
-            vec_rot = rotation_matrix * (vec - center_point) + center_point;
-            // find min max x
-            if (vec_rot[0] < min_x)
-                min_x = vec_rot[0];
-            if (vec_rot[0] > max_x)
-                max_x = vec_rot[0];
-            // separate point as two clusters(front and back), calc y values respectively
-            if (normal.transpose() * vec + line_param_c > 0)
-            {
-                y_values0 += vec_rot[1];
-                count0 += 1;
-            }
-            else
-            {
-                y_values1 += vec_rot[1];
-                count1 += 1;
-            }
-        }
-    }
-    // check if front and back both has points
-    if (count0 > 0 && count1 > 0)
-    {
-        y_values0 /= count0;
-        y_values1 /= count1;
+	// get line formula, normal is (cos(theta), sin(theta)), towards the long side
+	// the line formula is: nx * x + ny * y + (-(nx*cx+ny*cy)) = 0
+	Eigen::Vector2f normal, center_point;
+	normal << vec.x / sqrt(vec.x * vec.x + vec.y * vec.y), vec.y / sqrt(vec.x * vec.x + vec.y * vec.y);
+	center_point << car_wheel_information.center_x, car_wheel_information.center_y;
+	float line_param_c = -1 * center_point.transpose() * normal;
+	// get rotation matrix, get the angle towards normal vector, rather than x axis
+	// R = [ cos -sin]
+	//     [ sin  cos]
+	float rotate_angle = M_PI_2 - acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
+	Eigen::Matrix2f rotation_matrix;
+	rotation_matrix << cos(rotate_angle), -sin(rotate_angle), sin(rotate_angle), cos(rotate_angle);
+
+	// find min x and max x, separate y values according to the line, calculate difference between mean of y values as wheelbase
+	float min_x = 20, max_x = 0;
+	float y_values0 = 0, y_values1 = 0;
+	int count0 = 0, count1 = 0;
+	for (size_t i = 0; i < seg_clouds.size(); i++)
+	{
+		if (seg_clouds[i]->size() <= 0)
+			continue;
+		for (size_t j = 0; j < seg_clouds[i]->size(); j++)
+		{
+			// origin point and the point rotated around the origin
+			Eigen::Vector2f vec, vec_rot;
+			vec << seg_clouds[i]->points[j].x, seg_clouds[i]->points[j].y;
+			vec_rot = rotation_matrix * (vec - center_point) + center_point;
+			// find min max x
+			if (vec_rot[0] < min_x)
+				min_x = vec_rot[0];
+			if (vec_rot[0] > max_x)
+				max_x = vec_rot[0];
+			// separate point as two clusters(front and back), calc y values respectively
+			if (normal.transpose() * vec + line_param_c > 0)
+			{
+				y_values0 += vec_rot[1];
+				count0 += 1;
+			}
+			else
+			{
+				y_values1 += vec_rot[1];
+				count1 += 1;
+			}
+		}
+	}
+	// check if front and back both has points
+	if (count0 > 0 && count1 > 0)
+	{
+		y_values0 /= count0;
+		y_values1 /= count1;
 		car_wheel_information.wheel_base = fabs(y_values1 - y_values0);
 		car_wheel_information.wheel_width = fabs(min_x - max_x);
 //        LOG(INFO) << "--------detector find width, wheelbase: " << width << ", " << wheelbase << ", y means: [" << y_values0 << ", " << y_values1 << "] -----";
@@ -497,18 +497,18 @@ Common_data::Car_wheel_information& car_wheel_information, bool print)
 		p_cloud_in->points.push_back(pcl::PointXYZ(max_x, car_wheel_information.center_y, 0.0));
 		p_cloud_in->points.push_back(pcl::PointXYZ(car_wheel_information.center_x, y_values0, 0.0));
 		p_cloud_in->points.push_back(pcl::PointXYZ(car_wheel_information.center_x, y_values1, 0.0));
-    }
-    else
-    {
-        // calculate wheelbase according to corner points
-        // wheelbase = std::max(wheel_box.size.width, wheel_box.size.height);
-        // LOG(INFO) << "--------detector find border: [" << wheel_box.size.width << ", " << wheel_box.size.height << "] -----";
-        cv::RotatedRect wheel_center_box = cv::minAreaRect(corner_points);
+	}
+	else
+	{
+		// calculate wheelbase according to corner points
+		// wheelbase = std::max(wheel_box.size.width, wheel_box.size.height);
+		// LOG(INFO) << "--------detector find border: [" << wheel_box.size.width << ", " << wheel_box.size.height << "] -----";
+		cv::RotatedRect wheel_center_box = cv::minAreaRect(corner_points);
 		car_wheel_information.wheel_base = std::max(wheel_center_box.size.width, wheel_center_box.size.height);
 		car_wheel_information.wheel_width = std::min(wheel_box.size.width, wheel_box.size.height);
-    }
+	}
 
-    return Error_manager(Error_code::SUCCESS);
+	return Error_manager(Error_code::SUCCESS);
 }
 
 
@@ -536,8 +536,12 @@ Error_manager Region_detector::detect_ex(std::mutex* p_cloud_mutex, pcl::PointCl
 	std::cout << " huli test :::: " << " 112 = " << 112 << std::endl;
 	detect_wheel_ceres::Detect_result detect_result;
 	if(!m_detector_ceres.detect(seg_clouds, detect_result))
+	{
 		return Error_manager(Error_code::WJ_REGION_CLUSTER_SIZE_ERROR);
-	else {
+	}
+	else
+	{
+		std::unique_lock<std::mutex> t_lock(*p_cloud_mutex);
 		car_wheel_information.center_x = detect_result.cx;
 		car_wheel_information.center_y = detect_result.cy;
 		car_wheel_information.car_angle = detect_result.theta;

+ 106 - 12
wanji_lidar/region_worker.cpp

@@ -6,11 +6,16 @@
 
 Region_worker::Region_worker()
 {
-	m_region_worker_status = E_UNKNOW;
+	m_region_worker_status = E_UNKNOWN;
 
 	mp_cloud_collection_mutex = NULL;
 	mp_cloud_collection = NULL;
+
+	m_detect_updata_time = std::chrono::system_clock::now() - std::chrono::hours(1);
+
 	mp_auto_detect_thread = NULL;
+
+
 }
 
 /**
@@ -37,29 +42,116 @@ Error_manager Region_worker::init(Point2D_tool::Point2D_box point2D_box, std::mu
 	return Error_code::SUCCESS;
 }
 
-
-//唤醒自动预测的算法线程
-Error_manager Region_worker::wake_auto_detect()
+//开始自动预测的算法线程
+Error_manager Region_worker::start_auto_detect()
 {
 	//唤醒一次
 	m_auto_detect_condition.notify_all(false, true);
 	return Error_code::SUCCESS;
 }
+//关闭自动预测的算法线程
+Error_manager Region_worker::stop_auto_detect()
+{
+	//唤醒一次
+	m_auto_detect_condition.notify_all(false);
+	return Error_code::SUCCESS;
+}
 
 // 获得中心点、角度等测量数据
-Error_manager Region_worker::get_wheel_result(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in, Common_data::Car_wheel_information& car_wheel_information)
+Error_manager Region_worker::detect_wheel_result(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in, Common_data::Car_wheel_information& car_wheel_information)
 {
 	return m_detector.detect(p_cloud_mutex, p_cloud_in, car_wheel_information);
 }
 
 
 // 获得中心点、角度等测量数据,  新算法, 可以测量前轮旋转
-Error_manager Region_worker::get_wheel_result_ex(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in, Common_data::Car_wheel_information& car_wheel_information)
+Error_manager Region_worker::detect_wheel_result_ex(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_in, Common_data::Car_wheel_information& car_wheel_information)
 {
     return m_detector.detect_ex(p_cloud_mutex, p_cloud_in, car_wheel_information);
 }
 
 
+//外部调用获取新的车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会等待车轮定位信息刷新, 直到超时, (内置while)
+Error_manager Region_worker::get_new_wheel_information_and_wait(Common_data::Car_wheel_information* p_car_wheel_information,
+												 std::chrono::system_clock::time_point command_time, int timeout_ms)
+{
+	if ( p_car_wheel_information == NULL )
+	{
+		return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+							 "  POINTER IS NULL ");
+	}
+	//判断是否超时
+	while (std::chrono::system_clock::now() - command_time < std::chrono::milliseconds(timeout_ms))
+	{
+		//获取指令时间之后的信息, 如果没有就会循环
+		if(m_detect_updata_time > command_time  )
+		{
+			*p_car_wheel_information = m_car_wheel_information;
+			return Error_code::SUCCESS;
+		}
+		//else 等待下一次数据更新
+
+		//等1ms
+		std::this_thread::sleep_for(std::chrono::milliseconds(1));
+	}
+	//超时退出就报错
+	return Error_manager(Error_code::WJ_REGION_EMPTY_NO_WHEEL_INFORMATION, Error_level::MINOR_ERROR,
+						 " Region_worker::get_new_wheel_information_and_wait error ");
+}
+
+//外部调用获取当前车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会报错, 不会等待
+Error_manager Region_worker::get_current_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
+											std::chrono::system_clock::time_point command_time)
+{
+	if ( p_car_wheel_information == NULL )
+	{
+	    return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+	    					"  POINTER IS NULL ");
+	}
+	//获取指令时间之后的信息, 如果没有就会报错, 不会等待
+	if( m_detect_updata_time > command_time )
+	{
+		*p_car_wheel_information = m_car_wheel_information;
+		return Error_code::SUCCESS;
+	}
+	else
+	{
+		return Error_manager(Error_code::WJ_REGION_EMPTY_NO_WHEEL_INFORMATION, Error_level::MINOR_ERROR,
+							 " Region_worker::get_current_wheel_information error ");
+	}
+}
+//外部调用获取最新的车轮定位信息, 获取指令时间往前一个周期内的车轮定位信息, 如果没有就会报错, 不会等待
+Error_manager Region_worker::get_last_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
+										 std::chrono::system_clock::time_point command_time)
+{
+	if ( p_car_wheel_information == NULL )
+	{
+		return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+							 "  POINTER IS NULL ");
+	}
+	//将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
+	//就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
+	if( m_detect_updata_time > command_time - std::chrono::milliseconds(REGION_WORKER_DETECT_CYCLE_MS) )
+	{
+		*p_car_wheel_information = m_car_wheel_information;
+		return Error_code::SUCCESS;
+	}
+	else
+	{
+		return Error_manager(Error_code::WJ_REGION_EMPTY_NO_WHEEL_INFORMATION, Error_level::MINOR_ERROR,
+							 " Region_worker::get_last_wheel_information error ");
+	}
+}
+
+Region_worker::Region_worker_status Region_worker::get_status()
+{
+	return m_region_worker_status;
+}
+
+std::chrono::system_clock::time_point Region_worker::get_detect_updata_time()
+{
+	return m_detect_updata_time;
+}
 
 
 
@@ -115,7 +207,7 @@ void Region_worker::auto_detect_thread_fun()
 //
 //			auto start   = std::chrono::system_clock::now();
 
-			t_error = get_wheel_result_ex(mp_cloud_collection_mutex, mp_cloud_collection, m_car_wheel_information);
+			t_error = detect_wheel_result_ex(mp_cloud_collection_mutex, mp_cloud_collection, m_car_wheel_information);
 
 //			auto end   = std::chrono::system_clock::now();
 //			auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
@@ -124,6 +216,8 @@ void Region_worker::auto_detect_thread_fun()
 
 			if ( t_error == SUCCESS  )
 			{
+				std::unique_lock<std::mutex> t_lock(*mp_cloud_collection_mutex);
+				m_car_wheel_information.correctness = true;
 //				std::cout << " huli test :::: " << " x = " << m_car_wheel_information.center_x << std::endl;
 //				std::cout << " huli test :::: " << " y = " << m_car_wheel_information.center_y << std::endl;
 //				std::cout << " huli test :::: " << " c = " << m_car_wheel_information.car_angle << std::endl;
@@ -131,17 +225,17 @@ void Region_worker::auto_detect_thread_fun()
 //				std::cout << " huli test :::: " << " width = " << m_car_wheel_information.wheel_width << std::endl;
 //				std::cout << " huli test :::: " << " front_theta = " << m_car_wheel_information.front_theta << std::endl;
 //				std::cout << " huli test :::: " << " correctness = " << m_car_wheel_information.correctness << std::endl;
-				m_detect_updata_time = std::chrono::system_clock::now();
+
 			}
 			else
 			{
+				std::unique_lock<std::mutex> t_lock(*mp_cloud_collection_mutex);
+				m_car_wheel_information.correctness = false;
 //				std::cout << " huli test :::: " << " t_error = " << t_error << std::endl;
 			}
 
-
-//			std::cout << " huli test :::: " << " mp_cloud_collection->size() = " << mp_cloud_collection->size() << std::endl;
-
-			//huli
+			//无论结果如何,都要刷新时间, 表示这次定位已经执行了.
+			m_detect_updata_time = std::chrono::system_clock::now();
 		}
 	}
 	LOG(INFO) << " Wanji_manager::collect_cloud_thread_fun() end "<< this;

+ 40 - 17
wanji_lidar/region_worker.h

@@ -34,9 +34,13 @@ public:
 #define REGION_WORKER_HAS_CAR 2
 #define REGION_WORKER_DETECT_ERROR 3
 
-enum Region_worker_status
+//区域功能类 的预测算法的时间周期, 一般为100ms, 我们这里设一个较大值200ms
+#define REGION_WORKER_DETECT_CYCLE_MS	200
+
+//万集区域功能的状态
+	enum Region_worker_status
 	{
-		E_UNKNOW               	= 0,    //未知
+		E_UNKNOWN              	= 0,    //未知
 		E_READY               	= 1,    //准备,待机
 		E_BUSY					= 2, 	//工作正忙
 
@@ -45,38 +49,57 @@ enum Region_worker_status
 public:
 
 	Region_worker();
-    ~Region_worker();
+	~Region_worker();
 
 	Error_manager init(Point2D_tool::Point2D_box point2D_box, std::mutex* p_cloud_collection_mutex,
 					   pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud_collection);
 
-	//唤醒自动预测的算法线程
-	Error_manager wake_auto_detect();
+	//开始自动预测的算法线程
+	Error_manager start_auto_detect();
+	//关闭自动预测的算法线程
+	Error_manager stop_auto_detect();
+
+	// 获得中心点、角度等测量数据
+	Error_manager detect_wheel_result(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
+									  Common_data::Car_wheel_information& car_wheel_information);
+
+	// 获得中心点、角度等测量数据,  新算法, 可以测量前轮旋转
+	Error_manager detect_wheel_result_ex(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
+										 Common_data::Car_wheel_information& car_wheel_information);
+
+
+	//外部调用获取新的车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会等待车轮定位信息刷新, 直到超时, (内置while)
+	Error_manager get_new_wheel_information_and_wait(Common_data::Car_wheel_information* p_car_wheel_information,
+													 std::chrono::system_clock::time_point command_time, int timeout_ms=1500);
 
-    // 获得中心点、角度等测量数据
-    Error_manager get_wheel_result(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
-    Common_data::Car_wheel_information& car_wheel_information);
+	//外部调用获取当前车轮定位信息, 获取指令时间之后的车轮定位信息, 如果没有就会报错, 不会等待
+	Error_manager get_current_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
+												std::chrono::system_clock::time_point command_time);
+	//外部调用获取最新的车轮定位信息, 获取指令时间往前一个周期内的车轮定位信息, 如果没有就会报错, 不会等待
+	Error_manager get_last_wheel_information(Common_data::Car_wheel_information* p_car_wheel_information,
+											 std::chrono::system_clock::time_point command_time);
 
-    // 获得中心点、角度等测量数据,  新算法, 可以测量前轮旋转
-    Error_manager get_wheel_result_ex(std::mutex* p_cloud_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
-    Common_data::Car_wheel_information& car_wheel_information);
+
+public:
+	Region_worker_status get_status();
+
+	std::chrono::system_clock::time_point get_detect_updata_time();
 
 protected:
-    static cv::RotatedRect create_rotate_rect(float length,float width,float angle,float x,float y);
+	static cv::RotatedRect create_rotate_rect(float length,float width,float angle,float x,float y);
 
-    //自动预测的线程函数
-    void auto_detect_thread_fun();
+	//自动预测的线程函数
+	void auto_detect_thread_fun();
 
 protected:
 	//状态
-	Region_worker_status						m_region_worker_status;			//区域功能的状态
+	Region_worker_status						m_region_worker_status;			//万集区域功能的状态
 
-    Region_detector 							m_detector;                             // 区域检测算法实例
+	Region_detector 							m_detector;                             // 区域检测算法实例
 
 	//万集雷达的自动功能, 定时收集所有点云, 然后通知detect去计算车轮信息.
 	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;			//定位结果的更新时间.
 

+ 64 - 14
wanji_lidar/wanji_lidar_device.cpp

@@ -265,21 +265,20 @@ bool Wanji_lidar_device::is_ready()
 
 
 
-// 外部调用获取点云
-//input: p_mutex : 输入点云锁的指针
-//output: cloud : 输出点云智能指针, 本函数会将点云添加到cloud里面
-//input: command_time: 触发执行的时间点. 从command_time提前一个扫描周期, 然后取最新的点
-//input: timeout_ms:超时时间, 超时之后自动退出, 返回错误
-Error_manager Wanji_lidar_device::get_latest_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+//外部调用获取新的点云, 获取指令时间之后的点云, 如果没有就会等待点云刷新, 直到超时, (内置while)
+Error_manager Wanji_lidar_device::get_new_cloud_and_wait(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
 												   std::chrono::system_clock::time_point command_time, int timeout_ms)
 {
-	int t_scan_cycle_ms = m_protocol.get_scan_cycle();
+	if ( p_mutex == NULL || p_cloud.get() == NULL )
+	{
+	    return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+	    					"  POINTER IS NULL ");
+	}
 	//判断是否超时
 	while (std::chrono::system_clock::now() - command_time < std::chrono::milliseconds(timeout_ms))
 	{
-		//将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
-		//就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
-		if( m_protocol.get_scan_time() > command_time - std::chrono::milliseconds(t_scan_cycle_ms) )
+		//获取指令时间之后的点云, 如果没有就会循环
+		if( m_protocol.get_scan_time() > command_time  )
 		{
 			std::unique_lock<std::mutex> lck(*p_mutex);
 			Error_manager code = m_protocol.get_scan_points(p_cloud);
@@ -292,13 +291,41 @@ Error_manager Wanji_lidar_device::get_latest_cloud(std::mutex* p_mutex, pcl::Poi
 	}
 	//超时退出就报错
 	return Error_manager(Error_code::WJ_LIDAR_GET_CLOUD_TIMEOUT, Error_level::MINOR_ERROR,
-						 " Wanji_lidar_device::get_cloud error ");
+						 " Wanji_lidar_device::get_new_cloud_and_wait error ");
 }
 
-//外部获取当前的点云, 就是往前一个周期内的, 如果没有就会报错, 不会等待
+//外部调用获取当前点云, 获取指令时间之后的点云, 如果没有就会报错, 不会等待
 Error_manager Wanji_lidar_device::get_current_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
 													std::chrono::system_clock::time_point command_time)
 {
+	if ( p_mutex == NULL || p_cloud.get() == NULL )
+	{
+		return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+							 "  POINTER IS NULL ");
+	}
+	//获取指令时间之后的点云, 如果没有就会报错, 不会等待
+	if( m_protocol.get_scan_time() > command_time )
+	{
+		std::unique_lock<std::mutex> lck(*p_mutex);
+		Error_manager code = m_protocol.get_scan_points(p_cloud);
+		return code;
+	}
+	else
+	{
+		return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
+							 " Wanji_lidar_device::get_current_cloud error ");
+	}
+}
+
+//外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
+Error_manager Wanji_lidar_device::get_last_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+													std::chrono::system_clock::time_point command_time)
+{
+	if ( p_mutex == NULL || p_cloud.get() == NULL )
+	{
+		return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+							 "  POINTER IS NULL ");
+	}
 	int t_scan_cycle_ms = m_protocol.get_scan_cycle();
 	//将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
 	//就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
@@ -311,11 +338,34 @@ Error_manager Wanji_lidar_device::get_current_cloud(std::mutex* p_mutex, pcl::Po
 	else
 	{
 		return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
-							 " Wanji_lidar_device::get_current_cloud error ");
+							 " Wanji_lidar_device::get_last_cloud error ");
 	}
 }
 
-
+//外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
+//注:函数内部不加锁, 由外部统一加锁.
+Error_manager Wanji_lidar_device::get_last_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+												 std::chrono::system_clock::time_point command_time)
+{
+	if ( p_cloud.get() == NULL )
+	{
+		return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
+							 "  POINTER IS NULL ");
+	}
+	int t_scan_cycle_ms = m_protocol.get_scan_cycle();
+	//将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
+	//就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
+	if( m_protocol.get_scan_time() > command_time - std::chrono::milliseconds(t_scan_cycle_ms) )
+	{
+		Error_manager code = m_protocol.get_scan_points(p_cloud);
+		return code;
+	}
+	else
+	{
+		return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
+							 " Wanji_lidar_device::get_last_cloud error ");
+	}
+}
 
 Wanji_lidar_device::Wanji_lidar_device_status Wanji_lidar_device::get_status()
 {

+ 15 - 9
wanji_lidar/wanji_lidar_device.h

@@ -11,8 +11,9 @@
 class Wanji_lidar_device
 {
 public:
+	//万集设备身状态
 	enum Wanji_lidar_device_status
-	{//default  = 0
+	{
 		E_UNKNOWN              	= 0,    //未知
 		E_READY	             	= 1,    //正常待机
 		E_DISCONNECT			= 2,	//断连
@@ -21,6 +22,7 @@ public:
 
 		E_FAULT					=10,	//故障
 	};
+
 public:
     // 无参构造函数
     Wanji_lidar_device();
@@ -45,17 +47,21 @@ public:
 	//判断是否为待机,如果已经准备好,则可以执行任务。
 	bool is_ready();
 
-	// 外部调用获取点云, 获取最新的, 如果没有就会等待点云刷新
-	//input: p_mutex : 输入点云锁的指针
-	//output: cloud : 输出点云智能指针, 本函数会将点云添加到cloud里面
-	//input: command_time: 触发执行的时间点. 从command_time提前一个扫描周期, 然后取最新的点
-	//input: timeout_ms:超时时间, 超时之后自动退出, 返回错误
-	Error_manager get_latest_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+	//外部调用获取新的点云, 获取指令时间之后的点云, 如果没有就会等待点云刷新, 直到超时, (内置while)
+	Error_manager get_new_cloud_and_wait(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
 							std::chrono::system_clock::time_point command_time, int timeout_ms=1500);
 
-	//外部获取当前的点云, 就是往前一个周期内的, 如果没有就会报错, 不会等待
+	//外部调用获取当前点云, 获取指令时间之后的点云, 如果没有就会报错, 不会等待
 	Error_manager get_current_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+									std::chrono::system_clock::time_point command_time);
+	//外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
+	Error_manager get_last_cloud(std::mutex* p_mutex, pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
 							std::chrono::system_clock::time_point command_time);
+
+	//外部调用获取最新的点云, 获取指令时间往前一个周期内的点云, 如果没有就会报错, 不会等待
+	//注:函数内部不加锁, 由外部统一加锁.
+	Error_manager get_last_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud,
+								 std::chrono::system_clock::time_point command_time);
 public:
 	Wanji_lidar_device_status get_status();
 protected:
@@ -68,7 +74,7 @@ protected:
 
 protected:
 	//状态
-	Wanji_lidar_device_status 					m_wanji_lidar_device_status;
+	Wanji_lidar_device_status 					m_wanji_lidar_device_status;	//万集设备身状态
 
 	//子模块
 	Async_Client								m_async_client;		//异步客户端, 负责雷达通信, 接受雷达数据

+ 77 - 218
wanji_lidar/wanji_manager.cpp

@@ -7,7 +7,7 @@
 
 Wanji_manager::Wanji_manager()
 {
-	m_wanji_manager_status = E_UNKNOW;
+	m_wanji_manager_status = E_UNKNOWN;
 
 	mp_cloud_collection = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
 	m_cloud_updata_time = std::chrono::system_clock::now() - std::chrono::hours(1);
@@ -15,7 +15,6 @@ Wanji_manager::Wanji_manager()
 
 	mp_execute_thread = NULL;
 	mp_wanji_manager_task = NULL;
-	mp_task_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
 }
 Wanji_manager::~Wanji_manager()
 {
@@ -45,7 +44,7 @@ Error_manager Wanji_manager::wanji_manager_init_from_protobuf(wj::wjManagerParam
 {
 	LOG(INFO) << " ---wanji_manager_init_from_protobuf run--- "<< this;
 	Error_manager t_error;
-	if ( m_wanji_manager_status != E_UNKNOW)
+	if ( m_wanji_manager_status != E_UNKNOWN)
 	{
 		return Error_manager(Error_code::WJ_MANAGER_INIT_REPEAT, Error_level::MINOR_ERROR,
 							 " Wanji_manager::wanji_manager_init_from_protobuf init repeat error ");
@@ -137,10 +136,7 @@ Error_manager Wanji_manager::wanji_manager_uninit()
 	}
 	m_region_worker_map.clear();
 
-	m_wanji_manager_status = E_UNKNOW;
-
-	//回收下发雷达任务单
-	wanji_lidar_scan_task_map_clear_and_delete();
+	m_wanji_manager_status = E_UNKNOWN;
 
 	return Error_code::SUCCESS;
 }
@@ -178,7 +174,7 @@ Error_manager Wanji_manager::execute_task(Task_Base* p_wanji_manager_task)
 		mp_wanji_manager_task->set_task_statu(TASK_SIGNED);
 
 //启动雷达管理模块,的核心工作线程
-		m_wanji_manager_status = E_ISSUED_SCAN;
+		m_wanji_manager_status = E_BUSY;
 		m_execute_condition.notify_all(true);
 
 //将任务的状态改为 TASK_WORKING 处理中
@@ -207,13 +203,6 @@ Error_manager Wanji_manager::end_task()
 {
 	m_execute_condition.notify_all(false);
 
-	//释放下发的任务单
-	wanji_lidar_scan_task_map_clear_and_delete();
-	{
-		std::unique_lock<std::mutex> t_lock(m_task_cloud_mutex);
-		mp_task_cloud->clear();
-	}
-
 	if ( m_wanji_manager_status == E_BUSY ||
 	m_wanji_manager_status == E_ISSUED_SCAN ||
 	m_wanji_manager_status == E_WAIT_SCAN ||
@@ -245,6 +234,28 @@ Error_manager Wanji_manager::end_task()
 //取消任务单,由发送方提前取消任务单
 Error_manager Wanji_manager::cancel_task(Task_Base* p_wanji_manager_task)
 {
+	//关闭子线程
+	m_execute_condition.notify_all(false);
+	//确保内部线程已经停下
+	while (m_execute_condition.is_working())
+	{
+
+	}
+
+	//强制改为 TASK_DEAD,不管它当前在做什么。
+	mp_wanji_manager_task->set_task_statu(TASK_DEAD);
+
+	if ( m_wanji_manager_status == E_BUSY ||
+		 m_wanji_manager_status == E_ISSUED_SCAN ||
+		 m_wanji_manager_status == E_WAIT_SCAN ||
+		 m_wanji_manager_status == E_ISSUED_DETECT ||
+		 m_wanji_manager_status == E_WAIT_DETECT )
+	{
+		m_wanji_manager_status = E_READY;
+	}
+	//else 状态不变
+
+	return Error_code::SUCCESS;
 }
 
 //检查雷达状态,是否正常运行
@@ -310,46 +321,55 @@ void Wanji_manager::collect_cloud_thread_fun()
 		{
 			std::chrono::system_clock::time_point t_command_time = std::chrono::system_clock::now();
 			{
+				//全局加锁, 并清空点云.
 				std::unique_lock<std::mutex> t_lock(m_cloud_collection_mutex);
 				mp_cloud_collection->clear();
-			}
 
-			//重新收集当前的点云, 不允许阻塞
-			for (auto iter = m_wanji_lidar_device_map.begin(); iter != m_wanji_lidar_device_map.end(); ++iter)
-			{
-				t_error = iter->second->get_current_cloud(&m_cloud_collection_mutex,
-												mp_cloud_collection,t_command_time);
-				if ( t_error != Error_code::SUCCESS )
+				//重新收集最近的点云, 不允许阻塞
+				for (auto iter = m_wanji_lidar_device_map.begin(); iter != m_wanji_lidar_device_map.end(); ++iter)
 				{
-					t_result.compare_and_cover_error(t_error);
+					t_error = iter->second->get_last_cloud(mp_cloud_collection,t_command_time);
+					if ( t_error != Error_code::SUCCESS )
+					{
+						t_result.compare_and_cover_error(t_error);
+					}
 				}
-			}
 
-			if ( t_result == SUCCESS && mp_cloud_collection->size()>0 )
-			{
+				if ( t_result == SUCCESS && mp_cloud_collection->size()>0 )
 				{
-					std::unique_lock<std::mutex> t_lock(m_cloud_collection_mutex);
 					m_cloud_updata_time = std::chrono::system_clock::now();
+					//成功则唤醒预测算法
+					start_auto_detect();
+				}
+				else
+				{
+					mp_cloud_collection->clear();
+					//失败则关闭预测算法
+					stop_auto_detect();
 				}
-				wake_auto_detect();
 			}
-
-
-//			std::cout << " huli test :::: " << " mp_cloud_collection->size() = " << mp_cloud_collection->size() << std::endl;
-
-			//huli
 		}
 	}
 	LOG(INFO) << " Wanji_manager::collect_cloud_thread_fun() end "<< this;
 	return;
 }
 
-//唤醒自动预测的算法线程
-Error_manager Wanji_manager::wake_auto_detect()
+//开始自动预测的算法线程
+Error_manager Wanji_manager::start_auto_detect()
+{
+	for (auto iter = m_region_worker_map.begin(); iter != m_region_worker_map.end(); ++iter)
+	{
+	    iter->second->start_auto_detect();
+	}
+
+	return Error_code::SUCCESS;
+}
+//关闭自动预测的算法线程
+Error_manager Wanji_manager::stop_auto_detect()
 {
 	for (auto iter = m_region_worker_map.begin(); iter != m_region_worker_map.end(); ++iter)
 	{
-	    iter->second->wake_auto_detect();
+		iter->second->stop_auto_detect();
 	}
 
 	return Error_code::SUCCESS;
@@ -360,7 +380,7 @@ void Wanji_manager::execute_thread_fun()
 {
 	LOG(INFO) << " Wanji_manager::execute_thread_fun() start "<< this;
 	Error_manager t_error;
-	Error_manager t_result;
+	Common_data::Car_wheel_information t_car_wheel_information;
 
 	//雷达管理的独立线程,负责控制管理所有的雷达。
 	while (m_execute_condition.is_alive())
@@ -371,7 +391,6 @@ void Wanji_manager::execute_thread_fun()
 			std::this_thread::yield();
 			//重新循环必须清除错误码.
 			t_error.error_manager_clear_all();
-			t_result.error_manager_clear_all();
 
 			if ( mp_wanji_manager_task == NULL )
 			{
@@ -380,203 +399,43 @@ void Wanji_manager::execute_thread_fun()
 				m_execute_condition.notify_all(false);
 			}
 
-			switch ( m_wanji_manager_status )
+			//万集内部全自动运行, 只需要根据时间去获取想要的就行了.
+			//目前楚天是唯一的预测算法, 如果后续有多个出入口,则使用任务单的终端id来获取指定的.
+			if ( m_region_worker_map.size() > 0 )
 			{
-			    case E_ISSUED_SCAN:
-			    {
-					//第一步
-					//下发任务, 雷达管理模块给子雷达下发扫描任务.
-					//分发扫描任务给下面的雷达
-					//下发任务给所有的雷达
-					for (auto iter = m_wanji_lidar_device_map.begin(); iter != m_wanji_lidar_device_map.end(); ++iter)
+				t_error = m_region_worker_map[0]->get_current_wheel_information(&t_car_wheel_information, mp_wanji_manager_task->get_command_time());
+				if ( t_error == Error_code::SUCCESS )
+				{
+					//添加车轮的预测结果
+					mp_wanji_manager_task->set_car_wheel_information(t_car_wheel_information);
+					//正常完成任务
+					end_task();
+				}
+				else
+				{
+					//如果在指令时间1秒后都没有成功获取结果, 返回错误原因
+					if ( std::chrono::system_clock::now() - m_region_worker_map[0]->get_detect_updata_time() < std::chrono::milliseconds(WANJI_MANAGER_EXECUTE_TIMEOUT_MS)  )
 					{
-						//下发扫描任务
-						t_error = issued_scan_task(iter->first);
-						if ( t_error != SUCCESS)
-						{
-							//下发子任务的故障处理汇总
-							t_result.compare_and_cover_error(t_error);
-						}
+						//没有超时, 那么就等1ms, 然后重新循环
+						std::this_thread::sleep_for(std::chrono::milliseconds(1));
+						std::this_thread::yield();
 					}
-
-					//故障处理, 只处理2级以上的故障, 一级故障继续执行后面的
-					if(t_result.get_error_level() >= MINOR_ERROR)
+					else
 					{
-						m_wanji_manager_status = E_READY;
-						mp_wanji_manager_task->set_task_statu(TASK_ERROR);
 						//因为故障,而提前结束任务.
-						mp_wanji_manager_task->compare_and_cover_task_error_manager(t_result);
+						mp_wanji_manager_task->compare_and_cover_task_error_manager(t_error);
 						end_task();
 					}
-					else
-					{
-						//下发任务之后,修改状态为等待答复。
-						m_wanji_manager_status = E_WAIT_SCAN;
-					}
-			        break;
-			    }
-			    case E_WAIT_SCAN:
-			    {
-					//第二步
-					//等待答复, 注意不能写成死循环阻塞,
-					//子任务没完成就直接通过, 然后重新进入  while (m_laser_manager_condition.is_alive()),
-					// 这样线程仍然被 m_laser_manager_condition 控制
-					//循环检查任务的完成状态
-					std::map<int, Wanji_lidar_scan_task*>::iterator map_iter;
-					for (  map_iter = m_wanji_lidar_scan_task_map.begin(); map_iter != m_wanji_lidar_scan_task_map.end(); ++map_iter)
-					{
-						if ( map_iter->second->is_task_end() == false)
-						{
-							if ( map_iter->second->is_over_time() )
-							{
-								//超时处理。取消任务。
-								m_wanji_lidar_device_map[map_iter->first]->cancel_task(map_iter->second);
-								map_iter->second->set_task_statu(TASK_DEAD);
-								t_error.error_manager_reset(Error_code::WANJI_LIDAR_DEVICE_TASK_OVER_TIME, Error_level::MINOR_ERROR,
-															" Wanji_lidar_scan_task is_over_time ");
-								map_iter->second->set_task_error_manager(t_error);
-
-								continue;
-								//本次子任务超时死亡.直接进行下一个
-							}
-							else
-							{
-								//如果任务还在执行, 那就等待任务继续完成,等1us
-								std::this_thread::sleep_for(std::chrono::microseconds(1));
-								std::this_thread::yield();
-								break;
-								//注意了:这里break之后,map_iter不会指向 m_laser_task_map.end()
-								//这就表示仍然有子任务单没有结束.那就继续等待,,,直到所有任务完成或者超时.
-							}
-						}
-						//else 任务完成就判断下一个
-					}
-
-					//如果下发的任务全部结束,那么汇总所有的结果, 并销毁下发的任务单。
-					if(map_iter == m_wanji_lidar_scan_task_map.end() )
-					{
-						for (auto iter = m_wanji_lidar_scan_task_map.begin(); iter != m_wanji_lidar_scan_task_map.end(); )
-						{
-							//数据汇总,
-							//由于 cloud; 是所有任务单共用的,所以不用处理了。自动就在一起。
-
-							//错误汇总
-							t_result.compare_and_cover_error(iter->second->get_task_error_manager());
-
-							//销毁下发的任务单。
-							delete(iter->second);
-							iter = m_wanji_lidar_scan_task_map.erase(iter);
-							//注:erase 删除当前map_iter2之后返回下一个节点,当前的map_iter2无效化,
-						}
-
-						//故障处理, 只处理2级以上的故障, 一级故障继续执行后面的
-						if(t_result.get_error_level() >= MINOR_ERROR)
-						{
-							m_wanji_manager_status = E_READY;
-							mp_wanji_manager_task->set_task_statu(TASK_ERROR);
-							//因为故障,而提前结束任务.
-							mp_wanji_manager_task->compare_and_cover_task_error_manager(t_result);
-							end_task();
-						}
-						else
-						{
-							//下发任务之后,修改状态为等待答复。
-							m_wanji_manager_status = E_ISSUED_DETECT;
-						}
-					}
-					//else 直接通过, 然后重新进入  while (m_laser_manager_condition.is_alive())
-			        break;
-			    }
-				case E_ISSUED_DETECT:
-				{
-					m_wanji_manager_status = E_WAIT_DETECT;
-					break;
-				}
-				case E_WAIT_DETECT:
-				{
-					{
-						std::unique_lock<std::mutex> t_lock(m_task_cloud_mutex);
-						std::cout << " huli test :::: " << " mp_task_cloud->size() = " << mp_task_cloud->size() << std::endl;
-					}
 
-					mp_wanji_manager_task->compare_and_cover_task_error_manager(t_result);
-					//正常结束任务
-					end_task();
-					break;
 				}
-			    default:
-			    {
-
-			        break;
-			    }
 			}
 
-
-
-			//第3步, 下发预测算法任务
-			//huli
 		}
 	}
 	LOG(INFO) << " Wanji_manager::execute_thread_fun() end "<< this;
 	return;
 }
 
-//下发给子雷达任务。这里为下发雷达任务分配内存, 后续要记得回收 m_laser_task_map 。
-Error_manager Wanji_manager::issued_scan_task(int lidar_index)
-{
-	//判断是否存在
-	std::map<int, Wanji_lidar_device*>::iterator map_iter1 = m_wanji_lidar_device_map.find(lidar_index);
-	if ( map_iter1 == m_wanji_lidar_device_map.end() )
-	{
-		return Error_manager(Error_code::WJ_MANAGER_LASER_INDEX_ERRPR, Error_level::NEGLIGIBLE_ERROR,
-							 " issued_scan_task lidar_index  error ");
-	}
-
-	//查重
-	std::map<int, Wanji_lidar_scan_task*>::iterator map_iter2 = m_wanji_lidar_scan_task_map.find(lidar_index);
-	if ( map_iter2 != m_wanji_lidar_scan_task_map.end() )
-	{
-		//如果重复,则不做任何处理,视为无效行为.
-		//返回轻微错误.仅仅提示作用.
-		return Error_manager(Error_code::WJ_MANAGER_LASER_INDEX_REPEAT, Error_level::NEGLIGIBLE_ERROR,
-							 " issued_scan_task  lidar_index repeart ");
-	}
-
-	//创建雷达扫描任务,
-	// 这里为下发雷达任务分配内存,后续要记得回收。
-	Wanji_lidar_scan_task* t_wanji_lidar_scan_task=new Wanji_lidar_scan_task();
-	t_wanji_lidar_scan_task->task_init(TASK_CREATED, "",
-									   m_wanji_lidar_device_map[lidar_index],
-									   std::chrono::milliseconds(WANJI_716_SCAN_CYCLE_MS),
-									   mp_wanji_manager_task->get_command_time(),
-									   &m_task_cloud_mutex,
-									   mp_task_cloud	);
-
-
-	//保存雷达扫描任务 到 m_laser_task_map
-	m_wanji_lidar_scan_task_map[lidar_index] = t_wanji_lidar_scan_task;
-
-	//发送任务单给雷达
-	return m_wanji_lidar_device_map[lidar_index]->execute_task(t_wanji_lidar_scan_task);
-
-}
-
-
-//释放下发的任务单
-Error_manager Wanji_manager::wanji_lidar_scan_task_map_clear_and_delete()
-{
-	for ( auto map_iter2 = m_wanji_lidar_scan_task_map.begin(); map_iter2 != m_wanji_lidar_scan_task_map.end(); )
-	{
-		//销毁下发的任务单。
-		delete(map_iter2->second);
-		map_iter2 = m_wanji_lidar_scan_task_map.erase(map_iter2);
-		//注:erase 删除当前map_iter2之后返回下一个节点,当前的map_iter2无效化,
-		//for循环不用 ++map_iter2
-	}
-	return Error_code::SUCCESS;
-}
-
-
 
 
 

+ 11 - 16
wanji_lidar/wanji_manager.h

@@ -22,12 +22,15 @@ public:
 	// 子类必须把父类设定为友元函数,这样父类才能使用子类的私有构造函数。
 	friend class Singleton<Wanji_manager>;
 
-#define WANJI_MANAGER_PARAMETER_PATH	"../setting/wanji_manager.prototxt"
+	//万集管理任务超时时间1000ms,
+#define WANJI_MANAGER_EXECUTE_TIMEOUT_MS	1000
+//万集配置参数的默认路径
+#define WANJI_MANAGER_PARAMETER_PATH		"../setting/wanji_manager.prototxt"
 public:
 	//雷达管理的状态
 	enum Wanji_manager_status
 	{
-		E_UNKNOW               	= 0,    //未知
+		E_UNKNOWN              	= 0,    //未知
 		E_READY               	= 1,    //准备,待机
 		E_BUSY					= 2, 	//工作正忙
 
@@ -76,17 +79,16 @@ public://get or set member variable
 protected://member functions
 	//自动收集点云的线程函数
 	void collect_cloud_thread_fun();
-	//唤醒自动预测的算法线程
-	Error_manager wake_auto_detect();
+	//开始自动预测的算法线程
+	Error_manager start_auto_detect();
+	//关闭自动预测的算法线程
+	Error_manager stop_auto_detect();
+
+
 
 	//执行外界任务的执行函数
 	void execute_thread_fun();
 
-	//下发给子雷达任务。这里为下发雷达任务分配内存, 后续要记得回收 m_laser_task_map 。
-	Error_manager issued_scan_task(int lidar_index);
-	//释放下发的任务单
-	Error_manager wanji_lidar_scan_task_map_clear_and_delete();
-
 
 protected://member variable
 
@@ -112,13 +114,6 @@ protected://member variable
 
 	Wanji_manager_task*							mp_wanji_manager_task;			//万集管理模块的任务单的指针,内存由发送方管理。
 
-	std::mutex	 								m_task_cloud_mutex;       		//任务点云更新互斥锁
-	pcl::PointCloud<pcl::PointXYZ>::Ptr 		mp_task_cloud;					//任务点云集合, 内存由本类管理
-	std::map<int, Wanji_lidar_scan_task*>		m_wanji_lidar_scan_task_map;	//万集管理下发给雷达子模块的任务map,内存由本类管理
-
-//	std::map<int, Wanji_lidar_scan_task*>		m_wanji_lidar_scan_task_map;	//万集管理下发给雷达子模块的任务map,内存由本类管理
-
-
 
 private: