//
// Created by zx on 2020/7/1.
//

#ifndef DETECT_CERES_3D_HH
#define DETECT_CERES_3D_HH

#include <ceres/ceres.h>
#include <glog/logging.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/common/centroid.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
#include <chrono>
#include "boost/format.hpp"
#include "hybrid_grid.hpp"

class detect_ceres3d {
public:
    struct Loss_result
    {
        public: 
        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;
            this->rf_loss = loss_result.rf_loss;
            this->lb_loss = loss_result.lb_loss;
            this->rb_loss = loss_result.rb_loss;
            this->total_avg_loss = loss_result.total_avg_loss;
            return *this;
        }
    };
    struct Detect_result
    {
     public:
        double cx;
        double cy;
        double theta;
        bool success;
        Loss_result loss;
        Detect_result& operator=(const Detect_result& detect_result)
        {
            this->cx = detect_result.cx;
            this->cy = detect_result.cy;
            this->theta = detect_result.theta;
            this->success = detect_result.success;
            this->loss=detect_result.loss;
            return *this;
        }
    };
    detect_ceres3d(pcl::PointCloud<pcl::PointXYZ>::Ptr model_grid_cloud);
    ~detect_ceres3d();
    bool detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Detect_result &detect_result, std::string &error_info);
    bool detect(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Detect_result &detect_result,
                pcl::PointCloud<pcl::PointXYZ>::Ptr transformed_cloud,std::string &error_info);

protected:
    void save_model(std::string file);

 private:
    HybridGrid*                                  mp_model_grid;



};


#endif //DETECT_CERES_3D_HH
