/* * Copyright 2015-2019 Autoware Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Localization program using Normal Distributions Transform Yuki KITSUKAWA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include //#include #include //#include #include "ndtpos.pb.h" #include "ndtgpspos.pb.h" #include #include #include #include "ndt_matching.h" #include "modulecomm.h" #include "gnss_coordinate_convert.h" //the following are UBUNTU/LINUX ONLY terminal color codes. #define RESET "\033[0m" #define BLACK "\033[30m" /* Black */ #define RED "\033[31m" /* Red */ #define GREEN "\033[32m" /* Green */ #define YELLOW "\033[33m" /* Yellow */ #define BLUE "\033[34m" /* Blue */ #define MAGENTA "\033[35m" /* Magenta */ #define CYAN "\033[36m" /* Cyan */ #define WHITE "\033[37m" /* White */ #define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ #define BOLDRED "\033[1m\033[31m" /* Bold Red */ #define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ #define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ #define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ #define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ #define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ #define BOLDWHITE "\033[1m\033[37m" /* Bold White */ #define PREDICT_POSE_THRESHOLD 0.5 #define Wa 0.4 #define Wb 0.3 #define Wc 0.3 #include "ivfault.h" #include "ivlog.h" extern iv::Ivfault *gfault ; extern iv::Ivlog *givlog; static int gindex = 0; iv::lidar_pose glidar_pose; void * gpset; void * gppose; static bool g_hasmap = false; extern bool gbNeedReloc; enum class MethodType { PCL_GENERIC = 0, PCL_ANH = 1, PCL_ANH_GPU = 2, PCL_OPENMP = 3, }; static MethodType _method_type = MethodType::PCL_GENERIC; static pose initial_pose, predict_pose, predict_pose_imu, predict_pose_odom, predict_pose_imu_odom, previous_pose, ndt_pose, current_pose, current_pose_imu, current_pose_odom, current_pose_imu_odom, localizer_pose; static double offset_x, offset_y, offset_z, offset_yaw; // current_pos - previous_pose static double offset_imu_x, offset_imu_y, offset_imu_z, offset_imu_roll, offset_imu_pitch, offset_imu_yaw; static double offset_odom_x, offset_odom_y, offset_odom_z, offset_odom_roll, offset_odom_pitch, offset_odom_yaw; static double offset_imu_odom_x, offset_imu_odom_y, offset_imu_odom_z, offset_imu_odom_roll, offset_imu_odom_pitch, offset_imu_odom_yaw; // Can't load if typed "pcl::PointCloud map, add;" static pcl::PointCloud map, add; // If the map is loaded, map_loaded will be 1. static int map_loaded = 0; static int _use_gnss = 1; static int init_pos_set = 0; bool gbuseanh = true; static pcl::NormalDistributionsTransform ndt; static cpu::NormalDistributionsTransform anh_ndt; static cpu::NormalDistributionsTransform glocalanh_ndt; static pcl::NormalDistributionsTransform::Ptr ndtraw(new pcl::NormalDistributionsTransform()); static pcl::NormalDistributionsTransform::Ptr glocalndtraw(new pcl::NormalDistributionsTransform()); // Default values static int max_iter = 30; // Maximum iterations static float ndt_res = 1.0; // Resolution static double step_size = 0.1; // Step size static double trans_eps = 0.01; // Transformation epsilon static double exe_time = 0.0; static bool has_converged; static int iteration = 0; static double fitness_score = 0.0; static double trans_probability = 0.0; static double diff = 0.0; static double diff_x = 0.0, diff_y = 0.0, diff_z = 0.0, diff_yaw; static double current_velocity = 0.0, previous_velocity = 0.0, previous_previous_velocity = 0.0; // [m/s] static double current_velocity_x = 0.0, previous_velocity_x = 0.0; static double current_velocity_y = 0.0, previous_velocity_y = 0.0; static double current_velocity_z = 0.0, previous_velocity_z = 0.0; // static double current_velocity_yaw = 0.0, previous_velocity_yaw = 0.0; static double current_velocity_smooth = 0.0; static double current_velocity_imu_x = 0.0; static double current_velocity_imu_y = 0.0; static double current_velocity_imu_z = 0.0; static double current_accel = 0.0, previous_accel = 0.0; // [m/s^2] static double current_accel_x = 0.0; static double current_accel_y = 0.0; static double current_accel_z = 0.0; // static double current_accel_yaw = 0.0; static double angular_velocity = 0.0; static int use_predict_pose = 0; static std::chrono::time_point matching_start, matching_end; static int _queue_size = 1000; static double predict_pose_error = 0.0; static double _tf_x, _tf_y, _tf_z, _tf_roll, _tf_pitch, _tf_yaw; static Eigen::Matrix4f tf_btol; static std::string _localizer = "velodyne"; static std::string _offset = "linear"; // linear, zero, quadratic static bool _get_height = false; static bool _use_local_transform = false; static bool _use_imu = false; static bool _use_odom = false; static bool _imu_upside_down = false; static bool _output_log_data = false; static std::string _imu_topic = "/imu_raw"; static std::ofstream ofs; static std::string filename; //static sensor_msgs::Imu imu; //static nav_msgs::Odometry odom; // static tf::TransformListener local_transform_listener; static tf::StampedTransform local_transform; static unsigned int points_map_num = 0; pthread_mutex_t mutex; pthread_mutex_t mutex_read; pthread_mutex_t mutex_pose; bool gbNeedGPSUpdateNDT = false; pcl::PointCloud::Ptr local_map_ptr; pcl::PointCloud::Ptr global_map_ptr; pose glastmappose; static double imu_angular_velocity_x=0; static double imu_angular_velocity_y=0; static double imu_angular_velocity_z=0; static double imu_linear_acceleration_x=0; static double imu_linear_acceleration_y=0; static double imu_linear_acceleration_z =0; extern QFile * gpFileLastPos;//Save Last Positin static bool gbFileNDTUpdate; extern double garm_x ; extern double garm_y ; static int gndtcalcfailcount = 0; static pose gPoseReloc; static bool gbPoseReloc = false; #include //cv::Mat gmatimage; void ListenPoseSet(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname) { iv::lidar::ndtpos pos; if(false == pos.ParseFromArray(strdata,nSize)) { std::cout<<" ndtpos parse error."<::Ptr local_ptr(new pcl::PointCloud()); int nSize = global_map_ptr->size(); int i; for(i=0;iat(i); if(sqrt(pow(xp.x - current_pose.x,2)+pow(xp.y-current_pose.y,2)+pow(xp.z-current_pose.z,2))<30) { local_ptr->push_back(xp); } } glastmappose = current_pose; local_map_ptr = local_ptr; std::cout<<"current map size is "<size()< gvector_trace; extern void * gpa,* gpb ,* gpc, * gpd; iv::gpspos PoseToGPS(iv::gpspos xori,pose xpose) { double x_o,y_o; GaussProjCal(xori.lon,xori.lat,&x_o,&y_o); double lon,lat; double hdg_o = (90 - xori.heading)*M_PI/180.0; double rel_x = xpose.x * cos(hdg_o) - xpose.y * sin(hdg_o); double rel_y = xpose.x * sin(hdg_o) + xpose.y * cos(hdg_o); GaussProjInvCal(x_o + rel_x,y_o + rel_y,&lon,&lat); double hdg_c = hdg_o + xpose.yaw; hdg_c = M_PI/2.0 - hdg_c; double heading = hdg_c * 180.0/M_PI; while(heading < 0)heading = heading + 360; while(heading >360)heading = heading - 360; iv::gpspos xgpspos; xgpspos.lon = lon; xgpspos.lat = lat; xgpspos.height = xpose.z + xori.height; xgpspos.heading = heading; xgpspos.pitch = xpose.pitch*180.0/M_PI + xori.pitch; xgpspos.roll = xpose.roll*180.0/M_PI + xori.roll; xgpspos.ve = xpose.vx * cos(hdg_o) - xpose.vy * sin(hdg_o); xgpspos.vn = xpose.vx * sin(hdg_o) + xpose.vy * cos(hdg_o); // std::cout<< " ori heading : "<= gvector_trace.size()) { return 1000000.0; } int i; std::vector vt = gvector_trace.at(index).mvector_trace; int nsize = vt.size(); // std::cout<<"size is "< extern void pausecomm(); extern void continuecomm(); static void UseMap(int index) { pcl::PointCloud::Ptr xmap; xmap = boost::shared_ptr>(new pcl::PointCloud); QTime xTime; xTime.start(); if(0 == pcl::io::loadPCDFile(gvector_trace.at(index).mstrpcdpath.data(),*xmap)) { } else { std::cout<<"map size is 0"<::Ptr map_ptr(new pcl::PointCloud(*xmap)); // gvectoranh.push_back(new_anh_gpu_ndt_ptr); qDebug("ndt load finish time is %d",xTime.elapsed()); gcurmapindex = index; if(gbuseanh) { cpu::NormalDistributionsTransform localanhraw; localanhraw.setResolution(ndt_res); localanhraw.setInputTarget(map_ptr); localanhraw.setMaximumIterations(max_iter); localanhraw.setStepSize(step_size); localanhraw.setTransformationEpsilon(trans_eps); pthread_mutex_lock(&mutex); // ndt = glocal_ndt; glocalanh_ndt = localanhraw; pthread_mutex_unlock(&mutex); gbNeedUpdate = true; } else { pcl::NormalDistributionsTransform::Ptr localndtraw(new pcl::NormalDistributionsTransform()); localndtraw->setResolution(ndt_res); localndtraw->setInputTarget(map_ptr); localndtraw->setMaximumIterations(max_iter); localndtraw->setStepSize(step_size); localndtraw->setTransformationEpsilon(trans_eps); pthread_mutex_lock(&mutex); // ndt = glocal_ndt; glocalndtraw = localndtraw; pthread_mutex_unlock(&mutex); gbNeedUpdate = true; } std::cout<<"change map, index is "<= 0) { if(ftracedis < 30) { UseMap(index); ncurindex = index; g_hasmap = true; } } } else { if(index != ncurindex) { pose posex = CalcPose(gvector_trace[ncurindex].mndtorigin,gcurndtgpspos); double fnowdis = gettracedis(ncurindex,posex); if((fnowdis - ftracedis)>5) { UseMap(index); ncurindex = index; g_hasmap = true; } } } if(ftracedis > 50) { std::cout<0.0000005)||((fabs(xoldgpspos.lon - gcurndtgpspos.lon)>0.0000005))) { xoldgpspos = gcurndtgpspos; char str[1000]; snprintf(str,1000,"%11.7f\t%11.7f\t%9.3f\t%6.2f\t%6.2f\t%6.2f\n ", xoldgpspos.lon,xoldgpspos.lat,xoldgpspos.height, xoldgpspos.heading,xoldgpspos.pitch,xoldgpspos.roll); gpFileLastPos->seek(0); gpFileLastPos->write(str,strnlen(str,1000)); gpFileLastPos->flush(); } gbFileNDTUpdate = false; } } std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } void GPSPosMonitor(bool * pbRun) { if(gbGPSFix == false) { gcurndtgpspos = glastndtgpspos; } while(*pbRun) { int64_t nmsnow = std::chrono::system_clock::now().time_since_epoch().count()/1000000; if(abs(nmsnow - gnLastGPSTime)>1000) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } if(gbGPSFix == true) { double x0,y0; double x,y; GaussProjCal(gcurndtgpspos.lon,gcurndtgpspos.lat,&x0,&y0); GaussProjCal(gcurgpsgpspos.lon,gcurgpsgpspos.lat,&x,&y); double dis = sqrt(pow(x-x0,2)+ pow(y-y0,2)); double headdiff = fabs(gcurgpsgpspos.heading - gcurndtgpspos.heading); double zdiff = fabs(gcurgpsgpspos.height - gcurndtgpspos.height); if((dis> 10)||((headdiff>10)&&(headdiff<350))||(zdiff>5)||(g_hasmap == false)||(gbNeedGPSUpdateNDT)) { givlog->info("NDTFIX","gps fix ndt pos. dis:%f headdiff:%f zdiff:%f map %d ndt %d", dis,headdiff,zdiff,g_hasmap,gbNeedGPSUpdateNDT); std::cout<<"gps fix ndt pos "<<" dis: "<=0)&&(index < gvector_trace.size())) { } } } // else // { // if(gbgpsupdatendt) // { // gcurndtgpspos = gcurgpsgpspos; // gbgpsupdatendt = true; // current_velocity_x = 0; // current_velocity_y = 0; // current_velocity_z = 0; // angular_velocity = 0; // } // } } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void ndt_match_Init(pcl::PointCloud::Ptr mappcd) { _tf_x = 0; _tf_y = 0; _tf_z = 0; _tf_roll = 0; _tf_pitch = 0; _tf_yaw = 0; Eigen::Translation3f tl_btol(_tf_x, _tf_y, _tf_z); // tl: translation Eigen::AngleAxisf rot_x_btol(_tf_roll, Eigen::Vector3f::UnitX()); // rot: rotation Eigen::AngleAxisf rot_y_btol(_tf_pitch, Eigen::Vector3f::UnitY()); Eigen::AngleAxisf rot_z_btol(_tf_yaw, Eigen::Vector3f::UnitZ()); tf_btol = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix(); init_pos_set = 1; initial_pose.x = 0; initial_pose.y = 0; initial_pose.z = 0; initial_pose.roll = 0; initial_pose.pitch = 0; initial_pose.yaw = 0; localizer_pose.x = initial_pose.x; localizer_pose.y = initial_pose.y; localizer_pose.z = initial_pose.z; localizer_pose.roll = initial_pose.roll; localizer_pose.pitch = initial_pose.pitch; localizer_pose.yaw = initial_pose.yaw; previous_pose.x = initial_pose.x; previous_pose.y = initial_pose.y; previous_pose.z = initial_pose.z; previous_pose.roll = initial_pose.roll; previous_pose.pitch = initial_pose.pitch; previous_pose.yaw = initial_pose.yaw; current_pose.x = initial_pose.x; current_pose.y = initial_pose.y; current_pose.z = initial_pose.z; current_pose.roll = initial_pose.roll; current_pose.pitch = initial_pose.pitch; current_pose.yaw = initial_pose.yaw; current_velocity = 0; current_velocity_x = 0; current_velocity_y = 0; current_velocity_z = 0; angular_velocity = 0; // ndt.align(*output_cloud, Eigen::Matrix4f::Identity()); pcl::PointCloud::Ptr map_ptr(new pcl::PointCloud(*mappcd)); std::cout<<"map size is"<size()<size()<::Ptr filtered_scan(new pcl::PointCloud()); // pcl::VoxelGrid voxel_grid_filter; // voxel_grid_filter.setLeafSize(1.0,1.0,1.0); // voxel_grid_filter.setInputCloud(map_ptr); // voxel_grid_filter.filter(*filtered_scan); // std::cout<<"filter map size is "<size()<::Ptr output_cloud(new pcl::PointCloud); // ndt.align(*output_cloud, Eigen::Matrix4f::Identity()); gpset = iv::modulecomm::RegisterRecv("ndtposeset",ListenPoseSet); gppose = iv::modulecomm::RegisterSend("ndtpose",10000,3); if(map_ptr->size() == 0) { gbNDTRun = false; return; } pcl::PointCloud::Ptr dummy_scan_ptr(new pcl::PointCloud()); pcl::PointXYZ dummy_point; dummy_scan_ptr->push_back(dummy_point); if(map_ptr->size()>0)map_loaded = 1; // gpmapthread = new std::thread(LocalMapUpdate,1); } void ndt_match_Init_nomap() { _tf_x = 0; _tf_y = 0; _tf_z = 0; _tf_roll = 0; _tf_pitch = 0; _tf_yaw = 0; Eigen::Translation3f tl_btol(_tf_x, _tf_y, _tf_z); // tl: translation Eigen::AngleAxisf rot_x_btol(_tf_roll, Eigen::Vector3f::UnitX()); // rot: rotation Eigen::AngleAxisf rot_y_btol(_tf_pitch, Eigen::Vector3f::UnitY()); Eigen::AngleAxisf rot_z_btol(_tf_yaw, Eigen::Vector3f::UnitZ()); tf_btol = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix(); init_pos_set = 1; initial_pose.x = 0; initial_pose.y = 0; initial_pose.z = 0; initial_pose.roll = 0; initial_pose.pitch = 0; initial_pose.yaw = 0; localizer_pose.x = initial_pose.x; localizer_pose.y = initial_pose.y; localizer_pose.z = initial_pose.z; localizer_pose.roll = initial_pose.roll; localizer_pose.pitch = initial_pose.pitch; localizer_pose.yaw = initial_pose.yaw; previous_pose.x = initial_pose.x; previous_pose.y = initial_pose.y; previous_pose.z = initial_pose.z; previous_pose.roll = initial_pose.roll; previous_pose.pitch = initial_pose.pitch; previous_pose.yaw = initial_pose.yaw; current_pose.x = initial_pose.x; current_pose.y = initial_pose.y; current_pose.z = initial_pose.z; current_pose.roll = initial_pose.roll; current_pose.pitch = initial_pose.pitch; current_pose.yaw = initial_pose.yaw; current_velocity = 0; current_velocity_x = 0; current_velocity_y = 0; current_velocity_z = 0; angular_velocity = 0; gpmapthread = new std::thread(LocalMapUpdate,1); gbGFRun = true; gpgpsfixthread = new std::thread(GPSPosMonitor,&gbGFRun); gpsavelastthread = new std::thread(SaveMonitor,&gbGFRun); } void ndt_match_SetMap(pcl::PointCloud::Ptr mappcd) { if(mappcd->size() == 0 )return; pcl::PointCloud::Ptr map_ptr(new pcl::PointCloud(*mappcd)); pcl::PointCloud::Ptr dummy_scan_ptr(new pcl::PointCloud()); pcl::PointXYZ dummy_point; dummy_scan_ptr->push_back(dummy_point); if(map_ptr->size()>0)map_loaded = 1; } static double wrapToPm(double a_num, const double a_max) { if (a_num >= a_max) { a_num -= 2.0 * a_max; } return a_num; } static double wrapToPmPi(const double a_angle_rad) { return wrapToPm(a_angle_rad, M_PI); } static double calcDiffForRadian(const double lhs_rad, const double rhs_rad) { double diff_rad = lhs_rad - rhs_rad; if (diff_rad >= M_PI) diff_rad = diff_rad - 2 * M_PI; else if (diff_rad < -M_PI) diff_rad = diff_rad + 2 * M_PI; return diff_rad; } static unsigned int g_seq_old = 0; #include bool isfirst = true; #include std::vector gvectorimu; QMutex gMuteximu; static void lidar_imu_calc(qint64 current_lidar_time) { int nsize; int i; gMuteximu.lock(); nsize = gvectorimu.size(); for(i=0;i ximudata.imutime) { ximu_angular_velocity_x = ximudata.imu_angular_velocity_x; ximu_angular_velocity_y = ximudata.imu_angular_velocity_y; ximu_angular_velocity_z = ximudata.imu_angular_velocity_z; ximu_linear_acceleration_x = ximudata.imu_linear_acceleration_x; ximu_linear_acceleration_y = ximudata.imu_linear_acceleration_y; ximu_linear_acceleration_z = ximudata.imu_linear_acceleration_z; qint64 current_time_imu = ximudata.imutime; // givlog->verbose("NDT","imu time is %ld",current_time_imu); static qint64 previous_time_imu = current_time_imu; double diff_time = (current_time_imu - previous_time_imu); diff_time = diff_time/1000.0; if(diff_time < 0)diff_time = 0.000001; if(diff_time > 0.1)diff_time = 0.1; if(current_time_imu < previous_time_imu) { std::cout<<"current time is old "<verbose("NDT","imu x:%f y:%f z:%f yaw:%f",offset_imu_x, offset_imu_y,offset_imu_z,offset_imu_yaw); previous_time_imu = current_time_imu; } else { break;; } } if(i>0) { gvectorimu.erase(gvectorimu.begin(),gvectorimu.begin()+i); } gMuteximu.unlock(); // for(i=0;i ximudata.imutime) // { // gvectorimu.erase(gvectorimu.begin()) // } // } } static void imu_calc(qint64 current_time_imu) { static qint64 previous_time_imu = current_time_imu; double diff_time = (current_time_imu - previous_time_imu); diff_time = diff_time/1000.0; if(current_time_imu < previous_time_imu) { std::cout<<"current time is old "<verbose("NDT","imu x:%f y:%f z:%f yaw:%f",offset_imu_x, offset_imu_y,offset_imu_z,offset_imu_yaw); previous_time_imu = current_time_imu; } void imu_update(qint64 current_time_imu,double imu_roll,double imu_pitch,double imu_yaw, double acceleration_x,double acceleration_y, double acceleration_z) { // std::cout << __func__ << std::endl; // double imu_angular_velocity_x,imu_angular_velocity_y,imu_angular_velocity_z; static double previous_time_imu = current_time_imu; double diff_time = (current_time_imu - previous_time_imu); diff_time = diff_time/1000.0; imu_roll = imu_roll * M_PI/180.0; imu_pitch = imu_pitch * M_PI/180.0; imu_yaw = (-1.0)*imu_yaw * M_PI/180.0; imu_yaw = imu_yaw + 2.0*M_PI; // imu_pitch = 0; // imu_roll = 0; imu_roll = wrapToPmPi(imu_roll); imu_pitch = wrapToPmPi(imu_pitch); imu_yaw = wrapToPmPi(imu_yaw); static double previous_imu_roll = imu_roll, previous_imu_pitch = imu_pitch, previous_imu_yaw = imu_yaw; const double diff_imu_roll = imu_roll - previous_imu_roll; const double diff_imu_pitch = imu_pitch - previous_imu_pitch; double diff_imu_yaw; if (fabs(imu_yaw - previous_imu_yaw) > M_PI) { if (imu_yaw > 0) diff_imu_yaw = (imu_yaw - previous_imu_yaw) - M_PI * 2; else diff_imu_yaw = -M_PI * 2 - (imu_yaw - previous_imu_yaw); } else diff_imu_yaw = imu_yaw - previous_imu_yaw; imu_linear_acceleration_x = acceleration_x; // imu_linear_acceleration_y = acceleration_y; // imu_linear_acceleration_z = acceleration_z; imu_linear_acceleration_y = 0; imu_linear_acceleration_z = 0; if (diff_time != 0) { imu_angular_velocity_x = diff_imu_roll / diff_time; imu_angular_velocity_y = diff_imu_pitch / diff_time; imu_angular_velocity_z = diff_imu_yaw / diff_time; } else { imu_angular_velocity_x = 0; imu_angular_velocity_y = 0; imu_angular_velocity_z = 0; } iv::imudata ximudata; ximudata.imutime = current_time_imu; ximudata.imu_linear_acceleration_x = imu_linear_acceleration_x; ximudata.imu_linear_acceleration_y = imu_linear_acceleration_y; ximudata.imu_linear_acceleration_z = imu_linear_acceleration_z; ximudata.imu_angular_velocity_x = imu_angular_velocity_x; ximudata.imu_angular_velocity_y = imu_angular_velocity_y; ximudata.imu_angular_velocity_z = imu_angular_velocity_z; gMuteximu.lock(); gvectorimu.push_back(ximudata); gMuteximu.unlock(); // imu_calc(current_time_imu); previous_time_imu = current_time_imu; previous_imu_roll = imu_roll; previous_imu_pitch = imu_pitch; previous_imu_yaw = imu_yaw; } void restartndtfailcount() { gndtcalcfailcount = 0; } void setrelocpose(pose xPose) { gPoseReloc = xPose; gbPoseReloc = true; } #ifdef TEST_CALCTIME int ncalc = 0; int gncalctotal = 0; #endif void point_ndt(pcl::PointCloud::Ptr raw_scan) { static bool bNeedUpdateVel = false; //if gps update ndt, need update velocity qint64 current_scan_time = raw_scan->header.stamp; static qint64 old_scan_time = current_scan_time; if(gbNDTRun == false)return; bool bNotChangev = false; if(gbgpsupdatendt == true) { std::cout<verbose("previos pose is %f %f",previous_pose.x,previous_pose.y); // if(map_loaded == 0) // { // std::cout<::Ptr filtered_scan(new pcl::PointCloud()); pcl::VoxelGrid voxel_grid_filter; voxel_grid_filter.setLeafSize(voxel_leaf_size, voxel_leaf_size, voxel_leaf_size); voxel_grid_filter.setInputCloud(raw_scan); voxel_grid_filter.filter(*filtered_scan); // std::cout<<"voxed time is "<header.seq<header.seq,raw_scan->header.stamp); // std::cout<<"raw scan size is "<size()<<" filtered scan size is "<size()<::Ptr filtered_scan_ptr(new pcl::PointCloud(*filtered_scan)); int scan_points_num = filtered_scan_ptr->size(); Eigen::Matrix4f t(Eigen::Matrix4f::Identity()); // base_link Eigen::Matrix4f t2(Eigen::Matrix4f::Identity()); // localizer std::chrono::time_point align_start, align_end, getFitnessScore_start, getFitnessScore_end; static double align_time, getFitnessScore_time = 0.0; // std::cout<<"run hear"<setInputSource(filtered_scan_ptr); } // Guess the initial gross estimation of the transformation // double diff_time = (current_scan_time - previous_scan_time).toSec(); double diff_time = 0.0; if(g_seq_old != 0) { if((raw_scan->header.seq - g_seq_old)>0) { diff_time = raw_scan->header.seq - g_seq_old; diff_time = diff_time * 0.1; } } g_seq_old = raw_scan->header.seq; diff_time = current_scan_time -old_scan_time; diff_time = diff_time/1000.0; old_scan_time = current_scan_time; if(diff_time<=0)diff_time = 0.1; if(diff_time>1.0)diff_time = 0.1; // std::cout<<"diff time is "<verbose("NDT","previous x:%f y:%f z:%f yaw:%f",previous_pose.x, previous_pose.y,previous_pose.z,previous_pose.yaw); // if (_use_imu == true && _use_odom == true) // imu_odom_calc(current_scan_time); if (_use_imu == true && _use_odom == false) { lidar_imu_calc((current_scan_time-0)); } // if (_use_imu == false && _use_odom == true) // odom_calc(current_scan_time); // if (_use_imu == true && _use_odom == true) // predict_pose_for_ndt = predict_pose_imu_odom; // else // if (_use_imu == true && _use_odom == false) // predict_pose_for_ndt = predict_pose_imu; // else if (_use_imu == false && _use_odom == true) // predict_pose_for_ndt = predict_pose_odom; // else // predict_pose_for_ndt = predict_pose; if (_use_imu == true && _use_odom == false) { predict_pose_for_ndt = predict_pose_imu; // predict_pose_for_ndt = predict_pose; // predict_pose_for_ndt.yaw = predict_pose_imu.yaw; } else { predict_pose_for_ndt = predict_pose; } predict_pose_for_ndt = predict_pose; //not use predict_pose_imu in shelan. if(fabs(predict_pose_for_ndt.x -previous_pose.x)>10) { predict_pose_for_ndt = previous_pose; } if(fabs(predict_pose_for_ndt.y -previous_pose.y)>10) { predict_pose_for_ndt = previous_pose; } // predict_pose_for_ndt = predict_pose; // predict_pose_for_ndt.pitch = 0; // predict_pose_for_ndt.roll = 0; givlog->verbose("NDT","pre x:%f y:%f z:%f yaw:%f",predict_pose_for_ndt.x, predict_pose_for_ndt.y,predict_pose_for_ndt.z,predict_pose_for_ndt.yaw); // qDebug("pre x:%f y:%f z:%f yaw:%f pitch: %f roll: %f",predict_pose_for_ndt.x, // predict_pose_for_ndt.y,predict_pose_for_ndt.z,predict_pose_for_ndt.yaw,predict_pose_for_ndt.pitch,predict_pose_for_ndt.roll); // predict_pose_for_ndt = predict_pose; Eigen::Translation3f init_translation(predict_pose_for_ndt.x, predict_pose_for_ndt.y, predict_pose_for_ndt.z); Eigen::AngleAxisf init_rotation_x(predict_pose_for_ndt.roll, Eigen::Vector3f::UnitX()); Eigen::AngleAxisf init_rotation_y(predict_pose_for_ndt.pitch, Eigen::Vector3f::UnitY()); Eigen::AngleAxisf init_rotation_z(predict_pose_for_ndt.yaw, Eigen::Vector3f::UnitZ()); Eigen::Matrix4f init_guess = (init_translation * init_rotation_z * init_rotation_y * init_rotation_x) * tf_btol; pcl::PointCloud::Ptr output_cloud(new pcl::PointCloud); // std::cout<<"before ndt time is "<::Ptr aligned(new pcl::PointCloud()); align_start = std::chrono::system_clock::now(); if(gbuseanh) { anh_ndt.align(*aligned,init_guess); } else ndtraw->align(*aligned,init_guess); align_end = std::chrono::system_clock::now(); if(xTime.elapsed()<90) std::cout<0) { std::cout<<" average calc time: "<hasConverged(); t = ndtraw->getFinalTransformation(); iteration = ndtraw->getFinalNumIteration(); getFitnessScore_start = std::chrono::system_clock::now(); fitness_score = ndtraw->getFitnessScore(); getFitnessScore_end = std::chrono::system_clock::now(); trans_probability = ndtraw->getTransformationProbability(); } if(trans_probability >= 1.0) { gndtcalcfailcount = 0; } else { gndtcalcfailcount++; } if(gndtcalcfailcount >= 30) { gbNeedReloc = true; } std::cout<<"score: "<(getFitnessScore_end - getFitnessScore_start).count() / 1000.0; pthread_mutex_unlock(&mutex); tf::Matrix3x3 mat_l; // localizer mat_l.setValue(static_cast(t(0, 0)), static_cast(t(0, 1)), static_cast(t(0, 2)), static_cast(t(1, 0)), static_cast(t(1, 1)), static_cast(t(1, 2)), static_cast(t(2, 0)), static_cast(t(2, 1)), static_cast(t(2, 2))); // Update localizer_pose localizer_pose.x = t(0, 3); localizer_pose.y = t(1, 3); localizer_pose.z = t(2, 3); mat_l.getRPY(localizer_pose.roll, localizer_pose.pitch, localizer_pose.yaw, 1); // std::cout<<" local pose x is "<(t2(0, 0)), static_cast(t2(0, 1)), static_cast(t2(0, 2)), static_cast(t2(1, 0)), static_cast(t2(1, 1)), static_cast(t2(1, 2)), static_cast(t2(2, 0)), static_cast(t2(2, 1)), static_cast(t2(2, 2))); // Update ndt_pose ndt_pose.x = t2(0, 3); ndt_pose.y = t2(1, 3); ndt_pose.z = t2(2, 3); // ndt_pose.x = localizer_pose.x; // ndt_pose.y = localizer_pose.y; // ndt_pose.z = localizer_pose.z; mat_b.getRPY(ndt_pose.roll, ndt_pose.pitch, ndt_pose.yaw, 1); givlog->verbose("NDT","calc x:%f y:%f z:%f yaw:%f",ndt_pose.x, ndt_pose.y,ndt_pose.z,ndt_pose.yaw); // Calculate the difference between ndt_pose and predict_pose predict_pose_error = sqrt((ndt_pose.x - predict_pose_for_ndt.x) * (ndt_pose.x - predict_pose_for_ndt.x) + (ndt_pose.y - predict_pose_for_ndt.y) * (ndt_pose.y - predict_pose_for_ndt.y) + (ndt_pose.z - predict_pose_for_ndt.z) * (ndt_pose.z - predict_pose_for_ndt.z)); // std::cout<<" pose error is "<verbose("NDT","USE PREDICT POSE"); current_pose.x = predict_pose_for_ndt.x; current_pose.y = predict_pose_for_ndt.y; current_pose.z = predict_pose_for_ndt.z; current_pose.roll = predict_pose_for_ndt.roll; current_pose.pitch = predict_pose_for_ndt.pitch; current_pose.yaw = predict_pose_for_ndt.yaw; } // std::cout<<" current pose x is "< 0) ? (diff / diff_time) : 0; current_velocity_x = (diff_time > 0) ? (diff_x / diff_time) : 0; current_velocity_y = (diff_time > 0) ? (diff_y / diff_time) : 0; current_velocity_z = (diff_time > 0) ? (diff_z / diff_time) : 0; angular_velocity = (diff_time > 0) ? (diff_yaw / diff_time) : 0; current_pose.vx = current_velocity_x; current_pose.vy = current_velocity_y; current_velocity_smooth = (current_velocity + previous_velocity + previous_previous_velocity) / 3.0; if (current_velocity_smooth < 0.2) { current_velocity_smooth = 0.0; } // bNotChangev = true; if((diff_time > 0)&&(bNotChangev == false)) { double aa = (current_velocity -previous_velocity)/diff_time; if(fabs(aa)>5.0) { givlog->verbose("NDT","aa is %f",aa); aa = fabs(5.0/aa); current_velocity = previous_velocity + aa*(current_velocity -previous_velocity); current_velocity_x = previous_velocity_x + aa *((current_velocity_x -previous_velocity_x)); current_velocity_y = previous_velocity_y + aa *((current_velocity_y -previous_velocity_y)); current_velocity_z = previous_velocity_z + aa *((current_velocity_z -previous_velocity_z)); } } current_accel = (diff_time > 0) ? ((current_velocity - previous_velocity) / diff_time) : 0; current_accel_x = (diff_time > 0) ? ((current_velocity_x - previous_velocity_x) / diff_time) : 0; current_accel_y = (diff_time > 0) ? ((current_velocity_y - previous_velocity_y) / diff_time) : 0; current_accel_z = (diff_time > 0) ? ((current_velocity_z - previous_velocity_z) / diff_time) : 0; // std::cout<<"fit time is "<Updatexyyaw(current_pose.x,current_pose.y,current_pose.yaw); current_pose_imu.x = current_pose.x; current_pose_imu.y = current_pose.y; current_pose_imu.z = current_pose.z; current_pose_imu.roll = current_pose.roll; current_pose_imu.pitch = current_pose.pitch; current_pose_imu.yaw = current_pose.yaw; current_velocity_imu_x = current_velocity_x; current_velocity_imu_y = current_velocity_y; current_velocity_imu_z = current_velocity_z; current_velocity_imu_z = 0; offset_imu_x = 0.0; offset_imu_y = 0.0; offset_imu_z = 0.0; offset_imu_roll = 0.0; offset_imu_pitch = 0.0; offset_imu_yaw = 0.0; // std::cout<<" vx is "<header.stamp/1000); ndtpos.set_ndt_time(QDateTime::currentMSecsSinceEpoch()); ndtpos.set_accel(current_accel); ndtpos.set_accel_x(current_accel_x); ndtpos.set_accel_y(current_accel_y); ndtpos.set_accel_z(current_accel_z); ndtpos.set_vel(current_velocity); ndtpos.set_vel_x(current_velocity_x); ndtpos.set_vel_y(current_velocity_y); ndtpos.set_vel_z(current_velocity_z); ndtpos.set_fitness_score(fitness_score); ndtpos.set_has_converged(has_converged); ndtpos.set_id(0); ndtpos.set_iteration(iteration); ndtpos.set_trans_probability(trans_probability); ndtpos.set_pose_pitch(current_pose.pitch); ndtpos.set_pose_roll(current_pose.roll); ndtpos.set_pose_yaw(current_pose.yaw); ndtpos.set_pose_x(current_pose.x); ndtpos.set_pose_y(current_pose.y); ndtpos.set_pose_z(current_pose.z); ndtpos.set_comp_time(xTime.elapsed()); int ndatasize = ndtpos.ByteSize(); char * strser = new char[ndatasize]; bool bSer = ndtpos.SerializeToArray(strser,ndatasize); if(bSer) { iv::modulecomm::ModuleSendMsg(gpc,strser,ndatasize); } else { std::cout<debug("ndtgpspos","lat:%11.7f lon:%11.7f height:%11.3f heading:%6.3f pitch:%6.3f roll:%6.3f vn:%6.3f ve:%6.3f vd:%6.3f trans_prob:%6.3f score:%6.3f", xndtgpspos.lat(),xndtgpspos.lon(),xndtgpspos.height(), xndtgpspos.heading(),xndtgpspos.pitch(),xndtgpspos.roll(), xndtgpspos.vn(),xndtgpspos.ve(),xndtgpspos.vd(), xndtgpspos.tras_prob(),xndtgpspos.score()); ndatasize = xndtgpspos.ByteSize(); strser = new char[ndatasize]; bSer = xndtgpspos.SerializeToArray(strser,ndatasize); if(bSer) { std::cout<<"share msg."<