|
@@ -0,0 +1,369 @@
|
|
|
+#include "lidar_bkz.h"
|
|
|
+
|
|
|
+
|
|
|
+static float V_theta[16] = {-15,-13,-11,-9,-7,-5,-3,-1,1,3,5,7,9,11,13,15};
|
|
|
+static float H_Beta[16] = {-2.5,-2.5 ,-2.5 ,-2.5,-2.5,-2.5 ,-2.5 ,-2.5,
|
|
|
+ 2.5,-2.5 ,-2.5 ,-2.5, -2.5,-2.5 ,-2.5 ,-2.5};
|
|
|
+
|
|
|
+float V_theta_32[32] =
|
|
|
+ { -20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,
|
|
|
+ 9,10,11};
|
|
|
+float H_Beta_32[32]= { 2.5, -2.5, 2.5, -2.5, 2.5, -2.5, 2.5, -2.5,
|
|
|
+ 2.5, -2.5, 2.5, -2.5, 2.5, -2.5, 2.5, -2.5,
|
|
|
+ 2.5, -2.5, 2.5, -2.5, 2.5, -2.5, 2.5, -2.5,
|
|
|
+ 2.5, -2.5, 2.5, -2.5, 2.5, -2.5, 2.5, -2.5};
|
|
|
+
|
|
|
+lidar_bkz::lidar_bkz(std::string strlidartype,std::string strlidarip,int ndataport ,int nctrlport ,int ndevport ,int nMotorHZ,double finclinationang_xaxis,
|
|
|
+ double finclinationang_yaxis ) {
|
|
|
+
|
|
|
+ mfinclinationang_xaxis = finclinationang_xaxis;
|
|
|
+ mfinclinationang_yaxis = finclinationang_yaxis;
|
|
|
+ pcl::PointCloud<pcl::PointXYZI>::Ptr point_cloud(
|
|
|
+ new pcl::PointCloud<pcl::PointXYZI>());
|
|
|
+
|
|
|
+ point_cloud->header.frame_id = "velodyne";
|
|
|
+ point_cloud->height = 1;
|
|
|
+ point_cloud->header.stamp = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count()/1000);
|
|
|
+ point_cloud->width = 0;
|
|
|
+ point_cloud->header.seq =0;
|
|
|
+ mpoint_cloud_temp = point_cloud;
|
|
|
+
|
|
|
+ mpdriver = new lidar_bkdriver(strlidarip,ndataport,nctrlport,ndevport,nMotorHZ);
|
|
|
+ if(strlidartype == "16z"){
|
|
|
+ mntype = 0;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ mntype = 1;
|
|
|
+ }
|
|
|
+ mpTheadDecode = new std::thread(&lidar_bkz::ThreadDecode,this);
|
|
|
+}
|
|
|
+
|
|
|
+lidar_bkz::~lidar_bkz(){
|
|
|
+ mbRun = false;
|
|
|
+ mpTheadDecode->join();
|
|
|
+ delete mpdriver;
|
|
|
+}
|
|
|
+
|
|
|
+void lidar_bkz::ThreadDecode()
|
|
|
+{
|
|
|
+ static double azutotal = 0.0;
|
|
|
+ static int g_seq = 0;
|
|
|
+
|
|
|
+ bool bLastAng = false;
|
|
|
+ unsigned short nlastend;
|
|
|
+
|
|
|
+ double finclinationang_xaxis = mfinclinationang_xaxis * M_PI/180.0;// atof(gstr_inclinationang_xaxis)*M_PI/180.0; //Inclination from x axis
|
|
|
+ double finclinationang_yaxis = mfinclinationang_yaxis * M_PI/180.0;// atof(gstr_inclinationang_yaxis)*M_PI/180.0; //Inclination from y axis
|
|
|
+ bool binclix = false;
|
|
|
+ bool bincliy = false;
|
|
|
+ if(fabs(finclinationang_xaxis)>0.00000001)binclix = true;
|
|
|
+ if(fabs(finclinationang_yaxis)>0.00000001)bincliy = true;
|
|
|
+
|
|
|
+ float cos_finclinationang_xaxis = static_cast<float>(cos(finclinationang_xaxis)) ;
|
|
|
+ float sin_finclinationang_xaxis = static_cast<float>(sin(finclinationang_xaxis));
|
|
|
+ float cos_finclinationang_yaxis = static_cast<float>(cos(finclinationang_yaxis));
|
|
|
+ float sin_finclinationang_yaxis = static_cast<float>(sin(finclinationang_yaxis));
|
|
|
+
|
|
|
+ while(mbRun)
|
|
|
+ {
|
|
|
+ std::shared_ptr<unsigned char> pdata_ptr;
|
|
|
+ int64_t nrecvtime;
|
|
|
+ int ndatasize = 0;
|
|
|
+ int nread = mpdriver->GetRecvData(pdata_ptr,nrecvtime,ndatasize);
|
|
|
+ if(nread == 1)
|
|
|
+ {
|
|
|
+ // std::cout<<"read "<<ndatasize<<std::endl;
|
|
|
+ if(ndatasize % 1184 != 0)
|
|
|
+ {
|
|
|
+ std::cout<<" data not complete. datasize: "<<ndatasize<<std::endl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ unsigned char * p = pdata_ptr.get();
|
|
|
+ int nPac = ndatasize/1184;
|
|
|
+ int k;
|
|
|
+ for(k=0;k<nPac;k++)
|
|
|
+ {
|
|
|
+ unsigned short * pang_start = (unsigned short * )(p+12);
|
|
|
+ unsigned short * pang_end = (unsigned short *)(p+14);
|
|
|
+ // std::cout<<"start: "<<*pang_start<<" end: "<<*pang_end<<std::endl;
|
|
|
+ (void)pang_end;
|
|
|
+ double ang_space = static_cast<double>(*pang_end - *pang_start) * 0.01/12.0;
|
|
|
+ if(mntype == 1)
|
|
|
+ {
|
|
|
+ ang_space = static_cast<double>(*pang_end - *pang_start) * 0.01/6.0;
|
|
|
+ }
|
|
|
+ if(bLastAng == true){
|
|
|
+ ang_space = static_cast<double>(*pang_end - nlastend) * 0.01/12.0;
|
|
|
+ if(mntype == 1)ang_space = static_cast<double>(*pang_end - nlastend) * 0.01/6.0;
|
|
|
+ nlastend = *pang_end;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ bLastAng = true;
|
|
|
+ nlastend = *pang_end;
|
|
|
+ }
|
|
|
+ // std::cout<<" ang space: "<<ang_space<<std::endl;
|
|
|
+ if(ang_space < 0)
|
|
|
+ {
|
|
|
+ if(mntype != 1)
|
|
|
+ ang_space = ang_space + 360.0/12.0;
|
|
|
+ else
|
|
|
+ ang_space = ang_space + 360.0/6.0;
|
|
|
+ std::cout<<" ang space in round: "<<ang_space<<std::endl;
|
|
|
+ if((ang_space < 0) || (ang_space > 1.0))
|
|
|
+ {
|
|
|
+ std::cout<<" fix ang space fail. "<<" ang space: "<<ang_space<<std::endl;
|
|
|
+ ang_space = 0.18;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int i;
|
|
|
+ int nheadlen = 32;
|
|
|
+ double fAzuAng = static_cast<double>(*pang_start) * 0.01;
|
|
|
+ // std::cout<<" ang : "<<fAzuAng<<std::endl;
|
|
|
+ int nchcount = 16;
|
|
|
+ if(mntype == 1)
|
|
|
+ {
|
|
|
+ nchcount = 32;
|
|
|
+ }
|
|
|
+ int nblocksize = nchcount * 6;
|
|
|
+ int nblockcount = 1184/nblocksize;
|
|
|
+
|
|
|
+ for(i=0;i<nblockcount;i++)
|
|
|
+ {
|
|
|
+ int j;
|
|
|
+ for(j=0;j<nchcount;j++)
|
|
|
+ {
|
|
|
+ unsigned char * pecho = (unsigned char *)(p +nheadlen + i*nblocksize + j*6);
|
|
|
+ unsigned short * prange;
|
|
|
+ unsigned char * pchch;
|
|
|
+ double frange;
|
|
|
+ unsigned char nch;
|
|
|
+ unsigned char intensity;
|
|
|
+ pchch = pecho;
|
|
|
+ prange = (unsigned short *)(pecho +3);
|
|
|
+ intensity = *(pecho + 5);
|
|
|
+ nch = *pchch;
|
|
|
+ frange = static_cast<double>(*prange);
|
|
|
+ frange = frange * 0.004;
|
|
|
+ if(nch<=nchcount){
|
|
|
+ double fAng = (-fAzuAng - H_Beta[nch] - mfRollAng) * M_PI/180.0;
|
|
|
+ double vtheta = V_theta[nch] * M_PI/180.0;
|
|
|
+ if(mntype == 1)
|
|
|
+ {
|
|
|
+ fAng = (-fAzuAng - H_Beta_32[nch] - mfRollAng) * M_PI/180.0;
|
|
|
+ vtheta = V_theta_32[nch] * M_PI/180.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ double x = frange * cos(fAng)* cos(vtheta);
|
|
|
+ double y = frange * sin(fAng)* cos(vtheta);
|
|
|
+ double z = frange * sin(vtheta);
|
|
|
+
|
|
|
+ pcl::PointXYZI point;
|
|
|
+ point.x = x;
|
|
|
+ point.y = y;
|
|
|
+ point.z = z;
|
|
|
+ point.intensity = intensity;
|
|
|
+
|
|
|
+ if(binclix)
|
|
|
+ {
|
|
|
+ float y,z;
|
|
|
+ y = point.y;z = point.z;
|
|
|
+ point.y = y*cos_finclinationang_xaxis +z*sin_finclinationang_xaxis;
|
|
|
+ point.z = z*cos_finclinationang_xaxis - y*sin_finclinationang_xaxis;
|
|
|
+ }
|
|
|
+ if(bincliy)
|
|
|
+ {
|
|
|
+ float z,x;
|
|
|
+ z = point.z;x = point.x;
|
|
|
+ point.z = z*cos_finclinationang_yaxis + x*sin_finclinationang_yaxis;
|
|
|
+ point.x = x*cos_finclinationang_yaxis - z*sin_finclinationang_yaxis;
|
|
|
+ }
|
|
|
+
|
|
|
+ mpoint_cloud_temp->points.push_back(point);
|
|
|
+ ++mpoint_cloud_temp->width;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<" channel error."<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fAzuAng = fAzuAng + ang_space;
|
|
|
+
|
|
|
+ azutotal = azutotal + ang_space;
|
|
|
+ if(azutotal>=360.0)
|
|
|
+ {
|
|
|
+ //share pointcloud
|
|
|
+ mmutexpc.lock();
|
|
|
+ mpoint_cloud = mpoint_cloud_temp;
|
|
|
+ mbpcupdate = true;
|
|
|
+ mmutexpc.unlock();
|
|
|
+ mcv.notify_all();
|
|
|
+ pcl::PointCloud<pcl::PointXYZI>::Ptr point_cloud(
|
|
|
+ new pcl::PointCloud<pcl::PointXYZI>());
|
|
|
+
|
|
|
+ point_cloud->header.frame_id = "velodyne";
|
|
|
+ point_cloud->height = 1;
|
|
|
+ point_cloud->header.stamp = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count()/1000);
|
|
|
+ point_cloud->width = 0;
|
|
|
+ point_cloud->header.seq =g_seq;
|
|
|
+ g_seq++;
|
|
|
+ mpoint_cloud_temp = point_cloud;
|
|
|
+ azutotal = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p= p+ 1184;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void lidar_bkz::ThreadDecode32()
|
|
|
+{
|
|
|
+ static double azutotal = 0.0;
|
|
|
+ static int g_seq = 0;
|
|
|
+
|
|
|
+ double finclinationang_xaxis = mfinclinationang_xaxis * M_PI/180.0;// atof(gstr_inclinationang_xaxis)*M_PI/180.0; //Inclination from x axis
|
|
|
+ double finclinationang_yaxis = mfinclinationang_yaxis * M_PI/180.0;// atof(gstr_inclinationang_yaxis)*M_PI/180.0; //Inclination from y axis
|
|
|
+ bool binclix = false;
|
|
|
+ bool bincliy = false;
|
|
|
+ if(fabs(finclinationang_xaxis)>0.00000001)binclix = true;
|
|
|
+ if(fabs(finclinationang_yaxis)>0.00000001)bincliy = true;
|
|
|
+
|
|
|
+ float cos_finclinationang_xaxis = static_cast<float>(cos(finclinationang_xaxis)) ;
|
|
|
+ float sin_finclinationang_xaxis = static_cast<float>(sin(finclinationang_xaxis));
|
|
|
+ float cos_finclinationang_yaxis = static_cast<float>(cos(finclinationang_yaxis));
|
|
|
+ float sin_finclinationang_yaxis = static_cast<float>(sin(finclinationang_yaxis));
|
|
|
+
|
|
|
+ while(mbRun)
|
|
|
+ {
|
|
|
+ std::shared_ptr<unsigned char> pdata_ptr;
|
|
|
+ int64_t nrecvtime;
|
|
|
+ int ndatasize = 0;
|
|
|
+ int nread = mpdriver->GetRecvData(pdata_ptr,nrecvtime,ndatasize);
|
|
|
+ if(nread == 1)
|
|
|
+ {
|
|
|
+ std::cout<<"read "<<ndatasize<<std::endl;
|
|
|
+ if(ndatasize % 1184 != 0)
|
|
|
+ {
|
|
|
+ std::cout<<" data not complete. datasize: "<<ndatasize<<std::endl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ unsigned char * p = pdata_ptr.get();
|
|
|
+ unsigned short * pang_start = (unsigned short * )(p+12);
|
|
|
+ unsigned short * pang_end = (unsigned short *)(p+14);
|
|
|
+ (void)pang_end;
|
|
|
+ double ang_space = 0.2;
|
|
|
+ int i;
|
|
|
+ int nheadlen = 32;
|
|
|
+ double fAzuAng = static_cast<double>(*pang_start) * 0.01;
|
|
|
+ for(i=0;i<6;i++)
|
|
|
+ {
|
|
|
+ int j;
|
|
|
+ for(j=0;j<32;j++)
|
|
|
+ {
|
|
|
+ unsigned char * pecho = (unsigned char *)(p +nheadlen + i*192 + j*6);
|
|
|
+ unsigned short * prange;
|
|
|
+ unsigned char * pchch;
|
|
|
+ double frange;
|
|
|
+ unsigned char nch;
|
|
|
+ unsigned char intensity;
|
|
|
+ pchch = pecho;
|
|
|
+ prange = (unsigned short *)(pecho +3);
|
|
|
+ intensity = *(pecho + 5);
|
|
|
+ nch = * pchch;
|
|
|
+ frange = static_cast<double>(*prange);
|
|
|
+ frange = frange * 0.004;
|
|
|
+ if(nch<=16){
|
|
|
+ double fAng = (-fAzuAng - H_Beta_32[nch] - mfRollAng) * M_PI/180.0;
|
|
|
+ double vtheta = V_theta_32[nch] * M_PI/180.0;
|
|
|
+ double x = frange * cos(fAng)* cos(vtheta);
|
|
|
+ double y = frange * sin(fAng)* cos(vtheta);
|
|
|
+ double z = frange * sin(vtheta);
|
|
|
+
|
|
|
+ pcl::PointXYZI point;
|
|
|
+ point.x = x;
|
|
|
+ point.y = y;
|
|
|
+ point.z = z;
|
|
|
+ point.intensity = intensity;
|
|
|
+
|
|
|
+ if(binclix)
|
|
|
+ {
|
|
|
+ float y,z;
|
|
|
+ y = point.y;z = point.z;
|
|
|
+ point.y = y*cos_finclinationang_xaxis +z*sin_finclinationang_xaxis;
|
|
|
+ point.z = z*cos_finclinationang_xaxis - y*sin_finclinationang_xaxis;
|
|
|
+ }
|
|
|
+ if(bincliy)
|
|
|
+ {
|
|
|
+ float z,x;
|
|
|
+ z = point.z;x = point.x;
|
|
|
+ point.z = z*cos_finclinationang_yaxis + x*sin_finclinationang_yaxis;
|
|
|
+ point.x = x*cos_finclinationang_yaxis - z*sin_finclinationang_yaxis;
|
|
|
+ }
|
|
|
+
|
|
|
+ mpoint_cloud_temp->points.push_back(point);
|
|
|
+ ++mpoint_cloud_temp->width;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ std::cout<<" channel error."<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fAzuAng = fAzuAng + ang_space;
|
|
|
+
|
|
|
+ azutotal = azutotal + ang_space;
|
|
|
+ if(azutotal>=360.0)
|
|
|
+ {
|
|
|
+ //share pointcloud
|
|
|
+ mmutexpc.lock();
|
|
|
+ mpoint_cloud = mpoint_cloud_temp;
|
|
|
+ mbpcupdate = true;
|
|
|
+ mmutexpc.unlock();
|
|
|
+ mcv.notify_all();
|
|
|
+ pcl::PointCloud<pcl::PointXYZI>::Ptr point_cloud(
|
|
|
+ new pcl::PointCloud<pcl::PointXYZI>());
|
|
|
+
|
|
|
+ point_cloud->header.frame_id = "velodyne";
|
|
|
+ point_cloud->height = 1;
|
|
|
+ point_cloud->header.stamp = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count()/1000);
|
|
|
+ point_cloud->width = 0;
|
|
|
+ point_cloud->header.seq =g_seq;
|
|
|
+ g_seq++;
|
|
|
+ mpoint_cloud_temp = point_cloud;
|
|
|
+ azutotal = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int lidar_bkz::GetPointCloud(pcl::PointCloud<pcl::PointXYZI>::Ptr & point_cloud)
|
|
|
+{
|
|
|
+ if(mbpcupdate == true)
|
|
|
+ {
|
|
|
+ mmutexpc.lock();
|
|
|
+ point_cloud = mpoint_cloud;
|
|
|
+ mbpcupdate = false;
|
|
|
+ mmutexpc.unlock();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ std::unique_lock<std::mutex> lk(mmutexcv);
|
|
|
+ if(mcv.wait_for(lk,std::chrono::milliseconds(10)) == std::cv_status::timeout)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+// std::cout<<" wait a pc."<<std::endl;
|
|
|
+ if(mbpcupdate == true)
|
|
|
+ {
|
|
|
+ mmutexpc.lock();
|
|
|
+ point_cloud = mpoint_cloud;
|
|
|
+ mbpcupdate = false;
|
|
|
+ mmutexpc.unlock();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|