Преглед изворни кода

wj manager错误清除debug,更新ceres模型,调试滤波器类功能并采集数据

yct пре 4 година
родитељ
комит
dd759d3b5f

+ 1 - 0
error_code/error_code.h

@@ -282,6 +282,7 @@ enum Error_code
     WJ_REGION_RECTANGLE_SIZE_ERROR,									//万集测量,矩形大小错误
     WJ_REGION_RECTANGLE_SYMMETRY_ERROR,								//万集测量,矩形对称错误
     WJ_REGION_CLUSTER_SIZE_ERROR,									//万集测量,簇大小错误
+    WJ_REGION_CERES_SOLVE_ERROR,                                    //万集测量,优化失败
 
 //万集管理模块
 	WJ_MANAGER_ERROR_BASE										= 0x06040000,

+ 1 - 1
setting/communication.prototxt

@@ -24,7 +24,7 @@ communication_parameters
 
 #   connect_string_vector:"tcp://192.168.2.233:2333"
 
-bind_string:"tcp://192.168.0.64:30009"
+bind_string:"tcp://192.168.0.64:30010"
 connect_string_vector:"tcp://192.168.0.64:30000"
 
 

+ 14 - 14
setting/wanji_manager.prototxt

@@ -13,7 +13,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.201"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -46,7 +46,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.202"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -79,7 +79,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.203"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -112,7 +112,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.204"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -145,7 +145,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.205"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -178,7 +178,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.206"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -211,7 +211,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.207"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -244,7 +244,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.208"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -277,7 +277,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.209"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -310,7 +310,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.210"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -343,7 +343,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.211"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -376,7 +376,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.212"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -409,7 +409,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.213"
-        port:2110
+        port:2112
     }
     transform
     {
@@ -442,7 +442,7 @@ wj_lidar
     net_config
     {
         ip_address:"192.168.2.214"
-        port:2110
+        port:2112
     }
     transform
     {

+ 41 - 1
system/system_executor.cpp

@@ -7,6 +7,9 @@
 #include "../system/system_communication.h"
 #include "../wanji_lidar/wanji_manager.h"
 #include "../tool/common_data.h"
+#include "../wanji_lidar/measure_filter.h"
+
+std::ofstream g_debug_file;
 
 System_executor::System_executor()
 {
@@ -30,6 +33,9 @@ Error_manager System_executor::system_executor_init(int threads_size, int termin
 //反初始化
 Error_manager System_executor::system_executor_uninit()
 {
+    if(g_debug_file.is_open())
+        g_debug_file.close();
+
 	m_thread_pool.thread_pool_uninit();
 	m_system_executor_status = SYSTEM_EXECUTOR_UNKNOW;
 	return Error_code::SUCCESS;
@@ -219,6 +225,11 @@ Error_manager System_executor::check_status()
 //定时发送状态信息
 Error_manager System_executor::encapsulate_send_status()
 {
+    if(!g_debug_file.is_open())
+    {
+        g_debug_file.open("./filter_debug_result.txt", std::ios::app);
+    }
+
 	Error_manager t_error;
 	//创建一条状态消息
 	message::Ground_status_msg t_ground_status_msg;
@@ -276,12 +287,41 @@ Error_manager System_executor::encapsulate_send_status()
         t_multi_status_msg.mutable_error_manager()->set_error_description(t_error.get_error_description(), t_error.get_description_length());
         std::string t_msg = t_multi_status_msg.SerializeAsString();
         System_communication::get_instance_references().encapsulate_msg(t_msg);
+
+//        // 记录滤波前后测量数据,用于判断测量精度变化
+//        static int t_line_count = 0;
+//        if(region_index == 6 && ++t_line_count < 120) {
+//            if (g_debug_file.is_open() && t_car_wheel_information.correctness) {
+//                g_debug_file << "basic:"<<t_line_count<<"\n" <<std::setprecision(6)<<std::setiosflags(std::ios::fixed)
+//                             << t_car_wheel_information.center_x << ", "
+//                             << t_car_wheel_information.center_y << ", "
+//                             << t_car_wheel_information.car_angle << ", "
+//                             << t_car_wheel_information.wheel_base << ", "
+//                             << t_car_wheel_information.wheel_width << ", "
+//                             << t_car_wheel_information.front_theta << std::endl;
+//            }
+//            Common_data::Car_wheel_information t_filtered_result;
+//            Error_manager ec = Measure_filter::get_instance_references().get_filtered_wheel_information(region_index - 1, t_filtered_result);
+//            if(ec==SUCCESS){
+//                if (g_debug_file.is_open()) {
+//                    g_debug_file << "filtered:"<<t_line_count<<"\n" <<std::setprecision(6)<<std::setiosflags(std::ios::fixed)
+//                                 << t_filtered_result.center_x << ", "
+//                                 << t_filtered_result.center_y << ", "
+//                                 << t_filtered_result.car_angle << ", "
+//                                 << t_filtered_result.wheel_base << ", "
+//                                 << t_filtered_result.wheel_width << ", "
+//                                 << t_filtered_result.front_theta << std::endl;
+//                }
+//            }else{
+//                LOG(WARNING)<<ec.to_string();
+//            }
+////            LOG(WARNING) << t_multi_status_msg.DebugString();
+//        }
 	}
 
 //	std::cout << " huli test :::: " << " t_ground_status_msg.DebugString() = "  << std::endl;
 //	std::cout << t_ground_status_msg.DebugString() << std::endl;
 
-//    LOG(WARNING) << t_ground_status_msg.DebugString();
 //	std::cout << " huli test :::: " << " t_ground_status_msg.DebugString() = " << t_ground_status_msg.DebugString() << std::endl;
 
 	return Error_code::SUCCESS;

+ 14 - 5
tool/common_data.h

@@ -6,12 +6,12 @@
 #define NNXX_TESTS_COMMON_DATA_H
 #include <chrono>
 #include <cmath>
-
+#include <string>
 class Common_data
 {
 public:
 	//万集雷达扫描周期66ms, (频率15hz), 一般设置大一些
-#define WANJI_716_SCAN_CYCLE_MS 		70
+#define WANJI_716_SCAN_CYCLE_MS 		75
 
 
 	//整车的测量信息
@@ -93,6 +93,13 @@ public:
 
 			return final_score;
 		}
+
+		std::string to_string()
+        {
+            char buf[512]={0};
+            sprintf(buf, "%.4f %.4f %.4f %.4f %.4f %.4f\n", center_x, center_y, car_angle, wheel_base, wheel_width, front_theta);
+            return std::string(buf);
+        }
 	};
 
 	// 带时间戳的四轮测量信息
@@ -111,10 +118,12 @@ public:
 			this->wheel_data -= other.wheel_data;
 			return *this;
 		}
-		Car_wheel_information_stamped& operator-(const Car_wheel_information_stamped& other)
+		Car_wheel_information_stamped operator-(const Car_wheel_information_stamped& other)
 		{
-			this->wheel_data -= other.wheel_data;
-			return *this;
+            Car_wheel_information_stamped t_info;
+            t_info = *this;
+            t_info.wheel_data -= other.wheel_data;
+			return t_info;
 		}
 		Car_wheel_information_stamped& operator/=(int scalar)
 		{

+ 113 - 51
wanji_lidar/detect_wheel_ceres.cpp

@@ -7,7 +7,7 @@
 #include <pcl/common/transforms.h>
 
 
-constexpr float kMinProbability = 0.0f;
+constexpr float kMinProbability = 0.01f;
 constexpr float kMaxProbability = 1.f - kMinProbability;
 constexpr float kMaxCorrespondenceCost = 1.f - kMinProbability;
 constexpr int kPadding = INT_MAX / 4;
@@ -63,10 +63,13 @@ public:
         m_costs_lr = 0.0;
         m_costs_rr = 0.0;
     }
-    template <typename T>
+        template <typename T>
     bool operator()(const T* const variable, T* residual) const {
         // 每一轮重新初始化残差值
         T costs[4]={T(0),T(0),T(0),T(0)};
+	std::vector<std::vector<T> > deviation_calc_vector;
+	deviation_calc_vector.resize(4);
+	T deviation_weight = T(0.05);
 
         T cx = variable[0];
         T cy = variable[1];
@@ -74,6 +77,13 @@ public:
         T length = variable[3];
         T width = variable[4];
         T theta_front = variable[5];
+        T theta_front_weight = T(0.8);
+        T wheel_length_img_ratio = variable[6];
+        T wheel_width_length_ratio = variable[7];
+        // [1/3, 5/3]
+        T limited_wheel_length_img_ratio = T(0.8) / (T(1) + ceres::exp(T(-wheel_length_img_ratio))) + T(0.75);
+        // [0.25, 0.35]
+        T limited_wheel_length_ratio = T(0.25) / (T(1) + ceres::exp(T(-wheel_width_length_ratio))) + T(0.25);
 
         //整车旋转
         Eigen::Rotation2D<T> rotation(theta);
@@ -107,11 +117,12 @@ public:
             const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_front;
             //旋转
             const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
-            interpolator.Evaluate(point_rotation(1, 0) * m_scale + rows / 2.0 + 0.5 + T(kPadding),
-                                  point_rotation(0, 0) * m_scale + cols / 2.0 + 0.5 + T(kPadding),
+            interpolator.Evaluate(point_rotation(1, 0) * limited_wheel_length_img_ratio / limited_wheel_length_ratio* m_scale + rows / 2.0 + 0.5 + T(kPadding),
+                                  point_rotation(0, 0) * limited_wheel_length_img_ratio * m_scale + cols / 2.0 + 0.5 + T(kPadding),
                                   &residual[i]);
+            //residual[i] += theta_front*theta_front_weight;
             costs[0] += residual[i];
-
+	    deviation_calc_vector[0].push_back(residual[i]);
         }
         //右前轮
         int right_front_num = m_right_front_cloud.size();
@@ -122,10 +133,12 @@ public:
             const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_front;
             //旋转
             const Eigen::Matrix<T, 2, 1> point_rotation = rotation_matrix_front * tanslate_point;
-            interpolator.Evaluate(point_rotation(1, 0) * m_scale + rows / 2.0 + 0.5 + T(kPadding),
-                                  point_rotation(0, 0) * m_scale + cols / 2.0 + 0.5 + T(kPadding),
+            interpolator.Evaluate(point_rotation(1, 0) * limited_wheel_length_img_ratio / limited_wheel_length_ratio* m_scale + rows / 2.0 + 0.5 + T(kPadding),
+                                  point_rotation(0, 0) * limited_wheel_length_img_ratio * m_scale + cols / 2.0 + 0.5 + T(kPadding),
                                   &residual[left_front_num + i]);
+            //residual[left_front_num + i] += theta_front*theta_front_weight;
             costs[1] += residual[left_front_num+i];
+	    deviation_calc_vector[1].push_back(residual[left_front_num+i]);
         }
         //左后轮
         int left_rear_num = m_left_rear_cloud.size();
@@ -136,44 +149,63 @@ public:
             //减去经过车辆旋转计算的左前中心
             const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_left_rear;
 
-            interpolator.Evaluate(tanslate_point(1, 0) * m_scale + rows / 2.0 + 0.5 + T(kPadding),
-                                  tanslate_point(0, 0) * m_scale + cols / 2.0 + 0.5 + T(kPadding),
+            interpolator.Evaluate(tanslate_point(1, 0) * limited_wheel_length_img_ratio / limited_wheel_length_ratio * m_scale + rows / 2.0 + 0.5 + T(kPadding),
+                                  tanslate_point(0, 0) * limited_wheel_length_img_ratio * m_scale + cols / 2.0 + 0.5 + T(kPadding),
                                   &residual[left_front_num + right_front_num + i]);
             costs[2] += residual[left_front_num + right_front_num + i];
+	    deviation_calc_vector[2].push_back(residual[left_front_num + right_front_num + i]);
         }
 
         //右后轮
-
+	int right_rear_num = m_right_rear_cloud.size();
         for (int i = 0; i < m_right_rear_cloud.size(); ++i) {
             const Eigen::Matrix<T, 2, 1> point((T(m_right_rear_cloud[i].x) - cx),
                                                (T(m_right_rear_cloud[i].y) - cy));
             //减去经过车辆旋转计算的左前中心
             const Eigen::Matrix<T, 2, 1> tanslate_point = rotation_matrix * point - wheel_center_normal_right_rear;
 
-            interpolator.Evaluate(tanslate_point(1, 0) * m_scale + rows / 2.0 + 0.5 + T(kPadding),
-                                  tanslate_point(0, 0) * m_scale + cols / 2.0 + 0.5 + T(kPadding),
+            interpolator.Evaluate(tanslate_point(1, 0) * limited_wheel_length_img_ratio / limited_wheel_length_ratio * m_scale + rows / 2.0 + 0.5 + T(kPadding),
+                                  tanslate_point(0, 0) * limited_wheel_length_img_ratio * m_scale + cols / 2.0 + 0.5 + T(kPadding),
                                   &residual[left_front_num + right_front_num + left_rear_num + i]);
             costs[3] += residual[left_front_num + right_front_num + left_rear_num + i];
+	    deviation_calc_vector[3].push_back(residual[left_front_num + right_front_num + left_rear_num + i]);
         }
 
+	// 前轮旋转loss
+	residual[left_front_num + right_front_num + left_rear_num + right_rear_num] = theta_front*theta_front_weight;
+	// 四轮方差loss
+	residual[left_front_num + right_front_num + left_rear_num + right_rear_num+1] = T(0);
+	//printf("--------------\n");
+	T avg_costs[4] = {T(costs[0]/T(left_front_num)), T(costs[1]/T(right_front_num)), T(costs[2]/T(left_rear_num)), T(costs[3]/T(right_rear_num))};
+	for (int i = 0; i < deviation_calc_vector.size(); ++i) {
+		T t_deviation = T(0);
+		for (int j = 0; j < deviation_calc_vector[i].size(); ++j) {
+			t_deviation += deviation_weight * ceres::abs(deviation_calc_vector[i][j] - avg_costs[i]);
+		}
+		residual[left_front_num + right_front_num + left_rear_num + right_rear_num+1] += t_deviation;
+		//printf("??? dev: %.6f\n", t_deviation);
+		//costs[i] = t_deviation;
+		//printf("dev: %.6f\n", costs[i]);
+	}
+
         char buf[30];
         memset(buf, 0, 30);
-        sprintf(buf, "%.7f", costs[0]);
+        sprintf(buf, "%.12f", costs[0]);
         m_costs_lf = std::stod(buf) / left_front_num;
 
         memset(buf, 0, 30);
-        sprintf(buf, "%.7f", costs[1]);
+        sprintf(buf, "%.12f", costs[1]);
         m_costs_rf = std::stod(buf) / right_front_num;
 
         memset(buf, 0, 30);
-        sprintf(buf, "%.7f", costs[2]);
+        sprintf(buf, "%.12f", costs[2]);
         m_costs_lr = std::stod(buf) / left_rear_num;
 
-
         memset(buf, 0, 30);
-        sprintf(buf, "%.7f", costs[3]);
-        m_costs_rr = std::stod(buf) / m_right_rear_cloud.size();
+        sprintf(buf, "%.12f", costs[3]);
+        m_costs_rr = std::stod(buf) / right_rear_num;
         // m_costs_lf = costs[0];
+	//printf("%.6f %.6f %.6f %.6f\n",m_costs_lf, m_costs_rf, m_costs_lr, m_costs_rr);
         return true;
     }
     void get_costs(double &lf, double &rf, double &lr, double &rr)
@@ -202,12 +234,12 @@ bool detect_wheel_ceres::update_mat(int rows, int cols)
         cv::Size size(n+2,n+2);
         cv::Rect rect(center-cv::Point(n/2,n/2),size);
         double x = n / double(L);
-        double sigma = 0.06;
+        double sigma = 0.05;
         double miu = 0.0;
         double scale = 0.02;
-        double translation = -0.05;
+        double translation = 0.03;
         double gauss_value = (scale/(sqrt(2*M_PI)*sigma))*exp(-pow(x-miu, 2)/(2*sigma*sigma))+translation;
-        double quadratic_value = x-0.08;
+        double quadratic_value = std::max(2*x-0.25, 0.045);
         // LOG(INFO) << rect.tl().x<<", "<<rect.tl().y<<", "<<rect.br().x<<", "<<rect.br().y;
         // 对内外分别取色
         cv::rectangle(map,rect,std::max(gauss_value, quadratic_value));
@@ -227,15 +259,16 @@ bool detect_wheel_ceres::update_mat(int rows, int cols)
 detect_wheel_ceres::detect_wheel_ceres()
 {
     int cols=800;
-    int rows=200;
+    int rows=800;
     update_mat(rows, cols);
 }
 detect_wheel_ceres::~detect_wheel_ceres(){}
 
 
 
-bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> cloud_vec, Detect_result &detect_result)
+bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> cloud_vec, Detect_result &detect_result, std::string &error_info)
 {
+    error_info="";
     //清理点云
     m_left_front_cloud.clear();
     m_right_front_cloud.clear();
@@ -357,14 +390,16 @@ bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> clou
     bool solve_result = false;
     double total_solve_time = 0;
     bool stop_sign = false;
-    for (int j = 2; j < 4&&!stop_sign; j++)
-    {
-        // double input_vars[] = {detect_result.cx, detect_result.cy, detect_result.theta, detect_result.wheel_base, detect_result.width, detect_result.front_theta};
-        double map_rows = map_cols * 1.0 / j ;
-        update_mat(map_rows, map_cols);
+    // for (int j = 2; j < 4&&!stop_sign; j++)
+    // {
+    //     // double input_vars[] = {detect_result.cx, detect_result.cy, detect_result.theta, detect_result.wheel_base, detect_result.width, detect_result.front_theta};
+    //     double map_rows = map_cols * 1.0 / j ;
+    //     update_mat(map_rows, map_cols);
+
+    // !!! 将车轮比例添加到优化模型中
         Detect_result t_detect_result = detect_result;
-        // 寻找最小loss值对应的初始旋转角
-        for (int i = -5; i < 6&&!stop_sign; i+=2)
+       // 寻找最小loss值对应的初始旋转角
+        for (int i = -3; i < 4&&!stop_sign; i+=6)
         {
             t_detect_result.theta = (-angle_x + i) * M_PI / 180.0;
             // printf("double x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n",input_vars[0],input_vars[1],input_vars[3],input_vars[4],input_vars[2],input_vars[5]);
@@ -377,7 +412,9 @@ bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> clou
                 t_detect_result.front_theta *= (-M_PI) / 180.0;
             }
             auto t1=std::chrono::system_clock::now();
-            bool current_result = Solve(t_detect_result, t_loss_result);
+	    std::string t_error_info;
+            bool current_result = Solve(t_detect_result, t_loss_result, t_error_info);
+    	    error_info = t_error_info;
             auto t2=std::chrono::system_clock::now();
             auto duration=t2-t1;
             static double second=0.0;
@@ -395,17 +432,17 @@ bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> clou
                 detect_result = t_detect_result;
                 solve_result = current_result;
                 loss_result = t_loss_result;
-                optimized_map_rows = map_rows;
+                // optimized_map_rows = map_rows;
                 calc_count++;
-                /*// 新增,优化时间足够长则认为已找到正确结果
-                if(second > 0.02)
-                {
-                    stop_sign = true;
-                    break;
-                }*/
+                // // 新增,优化时间足够长则认为已找到正确结果
+                // if(second > 0.02)
+                // {
+                //     stop_sign = true;
+                //     break;
+                // }
             }
         }
-    } 
+    // }
     // std::cout<<"solve time "<<total_solve_time<<std::endl;
     // LOG(INFO) << "final avg cost for four wheels: "<<whole_loss[0]<<" "<<whole_loss[1]<<" "<<whole_loss[2]<<" "<<whole_loss[3]<<" ";
 
@@ -421,6 +458,10 @@ bool detect_wheel_ceres::detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> clou
     // // LOG(INFO) <<"going to show img ";
     // Solve(detect_result, t_loss_result, true);
 
+//     printf(" x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n",
+//         detect_result.cx,detect_result.cy,detect_result.wheel_base,detect_result.width,detect_result.theta,detect_result.front_theta);
+    if(solve_result)
+        error_info="";
     return solve_result;
 
 }
@@ -569,7 +610,7 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, double &avg_loss)
 }
 
 
-bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_result, bool save_img)
+bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_result, std::string &error_info, bool save_img)
 {
     double SCALE=300.0;
     double cx=detect_result.cx;
@@ -578,17 +619,21 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_r
     double init_wheel_base=2.7;
     double init_width=1.55;
     double init_theta_front=0*M_PI/180.0;
+    // 车轮长图比, 比例取值1/3-5/3, 当前变量无限制
+    double init_wheel_length_img_ratio = 0;
+    // 车轮宽长比, 默认长为1,比例取值范围0.2-0.8, 当前变量范围无限制
+    double init_wheel_width_length_ratio = 0;
 
-    double variable[] = {cx,cy,init_theta,init_wheel_base,init_width,init_theta_front};
+    double variable[] = {cx, cy, init_theta, init_wheel_base, init_width, init_theta_front, init_wheel_length_img_ratio, init_wheel_width_length_ratio};
     // printf("solve x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n", variable[0], variable[1], variable[3], variable[4], variable[2], variable[5]);
     // 第二部分:构建寻优问题
     ceres::Problem problem;
     CostFunctor *cost_func = new CostFunctor(m_left_front_cloud,m_right_front_cloud,m_left_rear_cloud,m_right_rear_cloud,m_map,SCALE);
     //使用自动求导,将之前的代价函数结构体传入,第一个1是输出维度,即残差的维度,第二个1是输入维度,即待寻优参数x的维度。
     ceres::CostFunction* cost_function =new
-            ceres::AutoDiffCostFunction<CostFunctor, ceres::DYNAMIC, 6>(
+            ceres::AutoDiffCostFunction<CostFunctor, ceres::DYNAMIC, 8>(
                     cost_func,
-                    m_left_front_cloud.size()+m_right_front_cloud.size()+m_left_rear_cloud.size()+m_right_rear_cloud.size());
+                    m_left_front_cloud.size()+m_right_front_cloud.size()+m_left_rear_cloud.size()+m_right_rear_cloud.size()+2);
     problem.AddResidualBlock(cost_function, NULL, variable); //向问题中添加误差项,本问题比较简单,添加一个就行。
 
 
@@ -596,12 +641,18 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_r
     ceres::Solver::Options options;
     options.use_nonmonotonic_steps=false;
     options.linear_solver_type = ceres::DENSE_QR; //配置增量方程的解法
+    options.logging_type = ceres::LoggingType::SILENT;
     options.max_num_iterations=60;
     options.num_threads=3;
     options.minimizer_progress_to_stdout = false;//输出到cout
     ceres::Solver::Summary summary;//优化信息
     ceres::Solve(options, &problem, &summary);//求解!!!
 
+//    if(!summary.IsSolutionUsable())
+//    {
+//        error_info.append("检测失败\t");
+//        return false;
+//    }
     // std::cout << summary.BriefReport() << "\n";//输出优化的简要信息
     // debug_img(detect_result, loss_result, true);
     double loss=summary.final_cost/(m_left_front_cloud.size()+m_right_front_cloud.size()+m_left_rear_cloud.size()+m_right_rear_cloud.size());
@@ -621,28 +672,33 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_r
     //检验
     // printf("loss: %.5f\n", loss);
     // printf("middle x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n", variable[0], variable[1], variable[3], variable[4], variable[2], variable[5]);
-    if(loss>0.0115)
+    if(loss>0.005)
     {
+        error_info.append("总loss过大 ").append(std::to_string(loss)).append("\t");
 //        LOG(WARNING) <<"总loss过大 "<<loss;
         return false;
     }
-    if (detect_result.width < 1.350 || detect_result.width > 2.000 || detect_result.wheel_base > 3.150 || detect_result.wheel_base < 2.200)
+    if (detect_result.width < 1.25 || detect_result.width > 2.000 || detect_result.wheel_base > 3.200 || detect_result.wheel_base < 2.200)
     {
-//        LOG(WARNING) <<"宽度(1.35, 2.00) 轴距(2.20, 3.15): "<<detect_result.width<<", "<<detect_result.wheel_base;
+        error_info.append(std::string("宽度(1.25, 2.00) 轴距(2.20, 3.20): ").append(std::to_string(detect_result.width).append(", ").append(std::to_string(detect_result.wheel_base)).append("\t")));
+//        LOG(WARNING) <<"宽度(1.35, 2.00) 轴距(2.20, 3.30): "<<detect_result.width<<", "<<detect_result.wheel_base;
         return false;
     }
 
-    detect_result.width += 0.15; //车宽+10cm
-    // printf(" x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n",x,y,wheel_base,width,theta,front_theta);
+    detect_result.width += 0.22; //车宽一边+11cm
+//     printf(" x:%.3f  y: %.3f  wheel:%.3f  width:%.3f    theta : %.3f   front theta: %.3f\n",
+//             detect_result.cx,detect_result.cy,detect_result.wheel_base,detect_result.width,detect_result.theta,detect_result.front_theta);
 
     // //added by yct
     if(detect_result.theta > 120 || detect_result.theta < 60)
     {
+        error_info.append("总角度错误 ").append(std::to_string(detect_result.theta)).append("\t");
 //        LOG(WARNING) <<"总角度错误 "<<detect_result.theta;
         return false;
     }
     if(fabs(detect_result.front_theta)>35)
     {
+        error_info.append("前轮角度错误 ").append(std::to_string(detect_result.front_theta)).append("\t");
 //        LOG(WARNING) <<"前轮角度错误 "<<detect_result.front_theta;
         return false;
     }
@@ -659,17 +715,23 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_r
         loss_result.rb_loss = costs_rr;
         loss_result.total_avg_loss = loss;
         // std::cout << "222"<< std::endl;
-        if (costs_lf <= 1e-6 && costs_rf <= 1e-6 && costs_lr <= 1e-6 && costs_rr <= 1e-6)
+        if (costs_lf == costs_rf && costs_lf == costs_lf && costs_lf == costs_rr)// (costs_lf <= 1e-6 && costs_rf <= 1e-6 && costs_lr <= 1e-6 && costs_rr <= 1e-6)
         {
+	    return false;
             loss_result.lf_loss = loss;
             loss_result.rf_loss = loss;
             loss_result.lb_loss = loss;
             loss_result.rb_loss = loss;
         }
         // 判断每个轮子平均loss是否满足条件
-        double single_wheel_loss_threshold = 0.109;
+        double single_wheel_loss_threshold = 0.5;
         if(loss_result.lf_loss > single_wheel_loss_threshold || loss_result.rf_loss > single_wheel_loss_threshold  || loss_result.lb_loss > single_wheel_loss_threshold || loss_result.rb_loss > single_wheel_loss_threshold)
         {
+            error_info.append("四轮loss过大 ").append(std::to_string(loss_result.lf_loss)).append(", ")
+                    .append(std::to_string(loss_result.rf_loss)).append(", ")
+                    .append(std::to_string(loss_result.lb_loss)).append(", ")
+                    .append(std::to_string(loss_result.rb_loss)).append("\t");
+//            LOG(WARNING)<<error_info;
 //            LOG(WARNING) <<"四轮loss过大"<<loss_result.lf_loss<<", "<<loss_result.rf_loss<<", "<<loss_result.lb_loss<<", "<<loss_result.rb_loss;
             return false;
         }
@@ -685,7 +747,7 @@ bool detect_wheel_ceres::Solve(Detect_result &detect_result, Loss_result &loss_r
     Detect_result t_detect_result = detect_result;
     t_detect_result.theta *= -M_PI/180.0;
     t_detect_result.front_theta *= -M_PI/180.0;
-    t_detect_result.width -= 0.15;
+    t_detect_result.width -= 0.22;
     transform_src(t_detect_result);
 
     return true;

+ 14 - 14
wanji_lidar/detect_wheel_ceres.h

@@ -21,13 +21,13 @@ public:
     struct Detect_result
     {
         public: 
-        double cx = 0;
-        double cy = 0;
-        double theta = 0;
-        double wheel_base = 0;
-        double width = 0;
-        double front_theta = 0;
-        bool success = false;
+        double cx;
+        double cy;
+        double theta;
+        double wheel_base;
+        double width;
+        double front_theta; 
+        bool success; 
         Detect_result& operator=(const Detect_result detect_result)
         {
             this->cx = detect_result.cx;
@@ -43,11 +43,11 @@ public:
     struct Loss_result
     {
         public: 
-        double lf_loss = 0;
-        double rf_loss = 0;
-        double lb_loss = 0;
-        double rb_loss = 0;
-        double total_avg_loss = 0;
+        double lf_loss;
+        double rf_loss;
+        double lb_loss;
+        double rb_loss;
+        double total_avg_loss;
         Loss_result& operator=(const Loss_result& loss_result)
         {
             this->lf_loss = loss_result.lf_loss;
@@ -60,13 +60,13 @@ public:
     };
     detect_wheel_ceres();
     ~detect_wheel_ceres();
-    bool detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> cloud_vec, Detect_result &detect_result);
+    bool detect(std::vector<pcl::PointCloud<pcl::PointXYZ>> cloud_vec, Detect_result &detect_result, std::string &error_info);
 
 protected:
     void transform_src(Detect_result detect_result);
     bool update_mat(int rows, int cols);
     bool Solve(Detect_result &detect_result, double &avg_loss);
-    bool Solve(Detect_result &detect_result, Loss_result &loss_result, bool save_img=false);
+    bool Solve(Detect_result &detect_result, Loss_result &loss_result, std::string &error_info, bool save_img=false);
     void debug_img(Detect_result detect_result, Loss_result loss_result, bool save_img=false, std::string out_img_path="");
 
     void create_mark(double x,double y,double theta,pcl::PointCloud<pcl::PointXYZ>& cloud);

+ 18 - 5
wanji_lidar/measure_filter.h

@@ -16,10 +16,11 @@
 #include <chrono>
 #include <vector>
 #include <algorithm>
+#include "glog/logging.h"
 
-#define FILTER_SIZE 5
-#define MAX_QUEUE_SIZE 10
-#define MAX_TIME_INTERVAL_MILLI 1000 
+#define FILTER_SIZE 6
+#define MAX_QUEUE_SIZE 12
+#define MAX_TIME_INTERVAL_MILLI 9000
 
 class Measure_filter : public Singleton<Measure_filter>
 {
@@ -37,6 +38,7 @@ public:
     {
         if(!data.wheel_data.correctness)
             return;
+//        LOG(INFO) << data.wheel_data.to_string();
         // 未创建队列
         if (m_measure_results_map.find(terminal_id) == m_measure_results_map.end())
         {
@@ -66,7 +68,12 @@ public:
         // 检查数据量
         if(m_measure_results_map.find(terminal_id) == m_measure_results_map.end() || m_measure_results_map.find(terminal_id)->second.size() < FILTER_SIZE)
         {
-            return Error_manager(WJ_FILTER_LACK_OF_RESULT, MINOR_ERROR, "缺少足够用于滤波的结果");
+            return Error_manager(WJ_FILTER_LACK_OF_RESULT, MINOR_ERROR,
+                    (std::string("缺少足够用于滤波的结果")+
+                    std::to_string(terminal_id)+
+                    std::string(m_measure_results_map.find(terminal_id) == m_measure_results_map.end()?
+                        "end":
+                        std::to_string(m_measure_results_map.find(terminal_id)->second.size()))).c_str());
         }
         // 填充待滤波结果到数组
         std::deque<Common_data::Car_wheel_information_stamped>* tp_deque = &m_measure_results_map.find(terminal_id)->second;
@@ -92,6 +99,7 @@ public:
         // 排序,丢掉最高两个(即与均值偏差最大两个,剩下平均获得最终值)
         std::sort(t_sorted_score_vec.begin(), t_sorted_score_vec.end());
         Common_data::Car_wheel_information_stamped t_final_result;
+        int t_result_count = 0;
         for (size_t i = 0; i < t_score_vec.size(); i++)
         {
             if(t_score_vec[i] == t_sorted_score_vec[t_sorted_score_vec.size()-1] || t_score_vec[i] == t_sorted_score_vec[t_sorted_score_vec.size()-2])
@@ -99,10 +107,15 @@ public:
                 continue;
             }else{
                 t_final_result += t_result_vec[i];
+                t_result_count++;
             }
         }
-        t_final_result /= t_result_vec.size() - 2;
+        if(t_result_count<=0)
+            return Error_manager(WJ_FILTER_FLUCTUATING, MINOR_ERROR, "结果波动");
+        t_final_result /= t_result_count;
         result = t_final_result.wheel_data;
+
+//        LOG(INFO) << "\navg: \n\t"<<t_avg_result.wheel_data.to_string()<<"final: \t"<<t_final_result.wheel_data.to_string();
         return SUCCESS;
     }
 

+ 8 - 6
wanji_lidar/region_detect.cpp

@@ -34,6 +34,7 @@ Error_manager Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr p_
 	// 1.参数合法性检验
 	if (p_cloud->size() <= 0)
 		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
+//	std::cout<<"preprocess 000"<<std::endl;
 	// 2.直通滤波, 筛选xy
 	pcl::PassThrough<pcl::PointXYZ> pass;
 	pass.setInputCloud(p_cloud);
@@ -43,16 +44,16 @@ Error_manager Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr p_
 	pass.filter(*p_cloud);                                            //输出到结果指针
 	if (p_cloud->size() <= 0)
 		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
+//    std::cout<<"preprocess 111 "<<p_cloud->size()<<std::endl;
 	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 << p_cloud->size()<<","<<m_region_box.x_min<<","<<m_region_box.x_max<<","<<m_region_box.y_min<<","<<m_region_box.y_max<<std::endl;
+//    std::cout << "cloud size: "<<p_cloud->size()<<","<<m_region_box.x_min<<","<<m_region_box.x_max<<","<<m_region_box.y_min<<","<<m_region_box.y_max<<std::endl;
 	if (p_cloud->size() <= 0)
 		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
-
+//    std::cout<<"preprocess 222 "<<p_cloud->size()<<std::endl;
 	// 3.离群点过滤
 	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
 	sor.setInputCloud(p_cloud);
@@ -60,7 +61,7 @@ Error_manager Region_detector::preprocess(pcl::PointCloud<pcl::PointXYZ>::Ptr p_
 	sor.setStddevMulThresh(3.0); //标准差倍数
 	sor.setNegative(false);      //保留未滤波点(内点)
 	sor.filter(*p_cloud);      //保存滤波结果到cloud_filter
-
+//    std::cout<<"preprocess 333 "<<p_cloud->size()<<std::endl;
 	if (p_cloud->size() <= 0)
 		return Error_manager(Error_code::WJ_REGION_EMPTY_CLOUD);
 	else
@@ -533,9 +534,10 @@ Error_manager Region_detector::detect_ex(std::mutex* p_cloud_mutex, pcl::PointCl
 		return result;
 //	std::cout << " huli test :::: " << " 112 = " << 112 << std::endl;
 	detect_wheel_ceres::Detect_result detect_result;
-	if(!m_detector_ceres.detect(seg_clouds, detect_result))
+    std::string t_error_info;
+	if(!m_detector_ceres.detect(seg_clouds, detect_result, t_error_info))
 	{
-		return Error_manager(Error_code::WJ_REGION_CLUSTER_SIZE_ERROR);
+		return Error_manager(Error_code::WJ_REGION_CERES_SOLVE_ERROR, MINOR_ERROR, t_error_info.c_str());
 	}
 	else
 	{

+ 25 - 13
wanji_lidar/region_worker.cpp

@@ -142,7 +142,7 @@ Error_manager Region_worker::get_last_wheel_information(Common_data::Car_wheel_i
 	}
 	//将指令时间提前一个扫描周期, 然后获取这个时间后面的点云.
 	//就是说, 在收到指令的时候, 可以使用一个周期以前的数据, 不用获取最新的点云.
-	if( m_detect_updata_time > command_time - std::chrono::milliseconds(REGION_WORKER_DETECT_CYCLE_MS) )
+	if( m_detect_updata_time > command_time - std::chrono::milliseconds(REGION_WORKER_DETECT_CYCLE_MS*2) )
 	{
 		*p_car_wheel_information = m_car_wheel_information;
 		return Error_code::SUCCESS;
@@ -209,12 +209,16 @@ void Region_worker::auto_detect_thread_fun()
 	{
 		//暂时固定为一个扫描周期, 就循环一次
 		//后期可以根据每个小雷达的刷新情况, 实时更改总点云.....
+//        if(m_index==5)
+//            LOG(INFO) << "before wait";
 		m_auto_detect_condition.wait();
+//        if(m_index==5)
+//            LOG(INFO) << "after wait";
 		if ( m_auto_detect_condition.is_alive() )
 		{
 //			std::cout << " huli test :::: " << "  = " << "---------------------------------------------------------------------------------" << std::endl;
-//
-//			LOG(INFO) << " huli test :::: " << " mp_cloud_collection->size() = " << mp_cloud_collection->size();
+//            if(m_index==5)
+//			    LOG(INFO) << " huli test :::: " << " mp_cloud_collection->size() = " << mp_cloud_collection->size();
 //
 //			auto start   = std::chrono::system_clock::now();
 
@@ -229,25 +233,31 @@ void Region_worker::auto_detect_thread_fun()
 			{
 				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;
-//				std::cout << " huli test :::: " << " wheelbase = " << m_car_wheel_information.wheel_base << std::endl;
-//				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;
-
+//                if(m_index==5) {
+//                    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;
+//                    std::cout << " huli test :::: " << " wheelbase = " << m_car_wheel_information.wheel_base
+//                              << std::endl;
+//                    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;
+//                }
 			}
 			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;
+//				if(m_index==5)
+//                    LOG(WARNING)<< " t_error = " << t_error;
 			}
 
 			//无论结果如何,都要刷新时间, 表示这次定位已经执行了.
 			m_detect_updata_time = std::chrono::system_clock::now();
-			
+//            if(m_index==5)
+//                LOG(INFO) << "before filter";
 			// 测量正确,更新到滤波器
 			if(m_car_wheel_information.correctness)
 			{
@@ -256,6 +266,8 @@ void Region_worker::auto_detect_thread_fun()
 				t_wheel_info_stamped.measure_time = m_detect_updata_time;
 				Measure_filter::get_instance_references().update_data(m_index, t_wheel_info_stamped);
 			}
+//            if(m_index==5)
+//                LOG(INFO) << "after filter";
 		}
 	}
 	LOG(INFO) << " Wanji_manager::collect_cloud_thread_fun() end "<< this;

+ 2 - 0
wanji_lidar/wanji_lidar_device.cpp

@@ -358,10 +358,12 @@ Error_manager Wanji_lidar_device::get_last_cloud(pcl::PointCloud<pcl::PointXYZ>:
 	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);
+//		LOG(WARNING) << p_cloud->size();
 		return code;
 	}
 	else
 	{
+//        LOG(WARNING) << "get cloud failed.....";
 		return Error_manager(Error_code::WANJI_LIDAR_DEVICE_NO_CLOUD, Error_level::MINOR_ERROR,
 							 " Wanji_lidar_device::get_last_cloud error ");
 	}

+ 7 - 1
wanji_lidar/wanji_manager.cpp

@@ -74,7 +74,7 @@ Error_manager Wanji_manager::wanji_manager_init_from_protobuf(wj::wjManagerParam
 		t_point2d_box.x_min = wanji_parameters.regions(i).minx();
 		t_point2d_box.x_max = wanji_parameters.regions(i).maxx();
 		t_point2d_box.y_min = wanji_parameters.regions(i).miny();
-		t_point2d_box.y_min = wanji_parameters.regions(i).maxy();
+		t_point2d_box.y_max = wanji_parameters.regions(i).maxy();
 		// changed by yct, 传入终端index,仅普爱使用
 		t_error = p_region_worker->init(t_point2d_box, &m_cloud_collection_mutex, mp_cloud_collection, i);
 		if ( t_error != Error_code::SUCCESS )
@@ -328,13 +328,17 @@ void Wanji_manager::collect_cloud_thread_fun()
 				mp_cloud_collection->clear();
 
 				//重新收集最近的点云, 不允许阻塞
+				// added by yct, 测试雷达功能
+//				int get_cloud_count=0;
 				for (auto iter = m_wanji_lidar_device_map.begin(); iter != m_wanji_lidar_device_map.end(); ++iter)
 				{
 					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);
+//						LOG(WARNING) << "cloud timeout: "<<get_cloud_count;
 					}
+//                    get_cloud_count++;
 				}
 
 				if ( t_result == SUCCESS && mp_cloud_collection->size()>0 )
@@ -348,9 +352,11 @@ void Wanji_manager::collect_cloud_thread_fun()
 					mp_cloud_collection->clear();
 					//失败则关闭预测算法
 					stop_auto_detect();
+//					LOG(WARNING) << t_result.to_string();
 				}
 			}
 		}
+        t_result.error_manager_clear_all();
 	}
 	LOG(INFO) << " Wanji_manager::collect_cloud_thread_fun() end "<< this;
 	return;