diff --git a/HC_planeLocalization_test/HC_planeLocalization_test.cpp b/HC_planeLocalization_test/HC_planeLocalization_test.cpp index d2a1918..c176309 100644 --- a/HC_planeLocalization_test/HC_planeLocalization_test.cpp +++ b/HC_planeLocalization_test/HC_planeLocalization_test.cpp @@ -179,7 +179,15 @@ void _outputPlaneInfo(char* fileName, SSX_planeInfo planeInfo) std::ofstream sw(fileName); char dataStr[250]; - sprintf_s(dataStr, 250, "距离: %g, 方位: %g", planeInfo.distance, planeInfo.dirAngle_deg); + sprintf_s(dataStr, 250, "距离: %g (mm)", planeInfo.distance); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "偏离引导线: %g (mm)", planeInfo.deviation); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "前进方向: %g (度)", planeInfo.dirAngle_deg); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "机鼻点: (%g , %g, %g)", planeInfo.nosePoint.x, planeInfo.nosePoint.y, planeInfo.nosePoint.z); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "方向向量(轴向): (%g , %g, %g)", planeInfo.axis.x, planeInfo.axis.y, planeInfo.axis.z); sw << dataStr << std::endl; sw.close(); } @@ -249,15 +257,19 @@ void _outputRGBDScan_RGBD( sw.close(); } -void _outputRGBDScan_superCluster( +void _outputRGBDScan_superCluster_result( char* fileName, - std::vector>& scanLines + std::vector>& scanLines, + SSX_planeInfo& planePose ) { int lineNum = (int)scanLines.size(); std::ofstream sw(fileName); int realLines = lineNum; + if (planePose.nosePoint.z > 1e-4) + realLines += 1; + sw << "LineNum:" << realLines << std::endl; sw << "DataType: 0" << std::endl; sw << "ScanSpeed: 0" << std::endl; @@ -297,7 +309,7 @@ void _outputRGBDScan_superCluster( if (flag == 1) //机鼻 { rgb = { 255, 0, 0 }; - size = 10; + size = 20; } else if(flag == 2) //机身 { @@ -327,6 +339,40 @@ void _outputRGBDScan_superCluster( sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; } } + if (planePose.nosePoint.z > 1e-4) + { + sw << "Line_" << lineIdx << "_0_1" << std::endl; + lineIdx++; + rgb = { 255, 0, 0 }; + size = 20; + float x = (float)planePose.nosePoint.x; + float y = (float)planePose.nosePoint.y; + float z = (float)planePose.nosePoint.z; + sw << "{" << x << "," << y << "," << z << "}-"; + sw << "{0,0}-{0,0}-"; + sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl; + //输出姿态 + //输出方向线条 + rgb = { 0, 0, 255 }; + size = 5; + SVzNL3DPoint pt1, pt2; + pt1 = { planePose.nosePoint.x - planePose.axis.x * 2000.0, + planePose.nosePoint.y - planePose.axis.y * 2000.0, + planePose.nosePoint.z - planePose.axis.z * 2000.0 }; + pt2 = { planePose.nosePoint.x + planePose.axis.x * 40000.0, + planePose.nosePoint.y + planePose.axis.y * 40000.0, + planePose.nosePoint.z + planePose.axis.z * 40000.0 }; + sw << "Poly_" << lineIdx << "_2" << std::endl; + sw << "{" << pt1.x << "," << pt1.y << "," << pt1.z << "}-"; + sw << "{0,0}-{0,0}-"; + sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; + sw << "{" << pt2.x << "," << pt2.y << "," << pt2.z << "}-"; + sw << "{0,0}-{0,0}-"; + sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; + lineIdx++; + + } + sw.close(); } @@ -587,7 +633,7 @@ int main() for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { - //fidx =18; + //fidx =7; char _scan_file[256]; sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); @@ -623,16 +669,16 @@ int main() & errCode); long t2 = (long)GetTickCount64(); - printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1)); + printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode); //输出测试结果 #if _OUTPUT_DEBUG_DATA - sprintf_s(_scan_file, "%sresult\\%d_superCluster.txt", dataPath[grp], fidx); - _outputRGBDScan_superCluster(_scan_file, debugData); -#endif sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); - _outputRGBDScan_RGBD(_scan_file, scanLines); - sprintf_s(_scan_file, "%sresult\\%d_fillingPort_info.txt", dataPath[grp], fidx); + _outputRGBDScan_superCluster_result(_scan_file, debugData, planeInfo); +#endif + sprintf_s(_scan_file, "%sresult\\%d_planePise_info.txt", dataPath[grp], fidx); _outputPlaneInfo(_scan_file, planeInfo); + printf("done\n"); + printf(" distance=%f, devi=%f, angle=%f\n", planeInfo.distance, planeInfo.deviation, planeInfo.dirAngle_deg); } } #endif diff --git a/sourceCode/planeLocalization.cpp b/sourceCode/planeLocalization.cpp index af7a858..1e6f462 100644 --- a/sourceCode/planeLocalization.cpp +++ b/sourceCode/planeLocalization.cpp @@ -6,7 +6,9 @@ #include //version 1.0.0 : base version release to customer -std::string m_strVersion = " PlaneLocalization 1.0.0"; +//version 1.1.0 : Ż˻ǵȡûзɻ +//version 1.2.0 : ˻عзֵ +std::string m_strVersion = " PlaneLocalization 1.2.0"; const char* wd_PlaneLocalizationVersion(void) { return m_strVersion.c_str(); @@ -143,7 +145,7 @@ void _searchSuperCluster( a_superCluster.push_back(i); clusterFlags[i] = 1; } - else if (score > 0) + else //if (score > 0) { //:ʹZ SVzNL3DRangeD& chkROI = clusterROIs[i]; @@ -215,6 +217,48 @@ SVzNL3DRangeD _getSupcluster(std::vector& superClusterIndice, std::vector& a_cluster, + SVzNL3DPosition& nearestPoint, + SVzNLRangeD& distChkRange, + const double bodyHeight) +{ + nearestPoint.nPointIdx = 0; + nearestPoint.pt3D = { 0.0, 0.0, 0.0 }; + for (int i = 0; i < (int)a_cluster.size(); i++) + { + if (nearestPoint.pt3D.z < 1e-4) + nearestPoint = a_cluster[i]; + else if (nearestPoint.pt3D.z > a_cluster[i].pt3D.z) + nearestPoint = a_cluster[i]; + } + + //жǷǻǵ + std::vector chkPoints; + for (int i = 0; i < (int)a_cluster.size(); i++) + { + double dist = sqrt(pow(a_cluster[i].pt3D.x - nearestPoint.pt3D.x, 2) + pow(a_cluster[i].pt3D.z - nearestPoint.pt3D.z, 2)); + if ((dist >= distChkRange.min) && (dist <= distChkRange.max)) + chkPoints.push_back(a_cluster[i].pt3D); + } + if (chkPoints.size() < 2) + return false; + + SVzNLRangeD yRange = { chkPoints[0].y, chkPoints[0].y }; + for (int i = 1; i < (int)chkPoints.size(); i++) + { + yRange.min = yRange.min > chkPoints[i].y ? chkPoints[i].y : yRange.min; + yRange.max = yRange.max < chkPoints[i].y ? chkPoints[i].y : yRange.max; + } + + double height = yRange.max - yRange.min; + if (height > bodyHeight) + return true; + return false; +} + SSX_planeInfo wd_planeLocalization( std::vector< std::vector>& scanLines, const SSG_planeCalibPara groundCalibParam, @@ -228,7 +272,7 @@ SSX_planeInfo wd_planeLocalization( *errCode = 0; //ڲ double planeMinHeight = 4000; //С߶4 - double planeMinWidth = 25000; //С2.5 + double planeMinWidth = 2500; //С2.5 double nearFarTh = 80000.0; //Զֽ double groundHOffset = 200; //ȥ double bodyHeadJudge_lenTh = 20000.0; //ͷжϵijޡ20 @@ -236,6 +280,8 @@ SSX_planeInfo wd_planeLocalization( SVzNLRangeD sameRBodyRange = { 5000.0, 28000.0 }; //ԲͰΣԾǾΪ׼ SVzNLRangeD engineToNoseDistRange = { 12000.0, 16000.0 }; SVzNLRangeD bodyYRange = { groundCalibParam.planeHeight - 4500.0, groundCalibParam.planeHeight - 1500 }; //YΧ + SVzNLRangeD nearestPointNostChkDistRange = { 3500.0, 4500.0 }; + double minBodyHeight = 2000.0; SSX_planeInfo planePoseInfo; memset(&planePoseInfo, 0, sizeof(SSX_planeInfo)); @@ -527,16 +573,34 @@ SSX_planeInfo wd_planeLocalization( int planeClusterSize = (int)planeSuperCluster.size(); //Ѱһͷλ: ROIǰZС int noseClusterId = -1; + SVzNL3DPosition nosePoint; + nosePoint.nPointIdx = 0; + nosePoint.pt3D = { 0.0, 0.0, 0.0 }; for (int i = 0; i < planeClusterSize; i++) { int clusterId = planeSuperCluster[i]; SVzNL3DRangeD& a_roi = objClustersROIs[clusterId]; if ((a_roi.yRange.min < bodyYRange.min) && (a_roi.yRange.max > bodyYRange.max)) //ڻYΧ { - if(noseClusterId < 0) - noseClusterId = clusterId; - else if (objClustersROIs[noseClusterId].zRange.min > objClustersROIs[clusterId].zRange.min) - noseClusterId = clusterId; + SVzNL3DPosition nearestPoint; + bool validNoseCluster = _checkNosePoint( + objClusters[clusterId], + nearestPoint, + nearestPointNostChkDistRange, + minBodyHeight); + if (true == validNoseCluster) + { + if (noseClusterId < 0) + { + noseClusterId = clusterId; + nosePoint = nearestPoint; + } + else if (nosePoint.pt3D.z > nearestPoint.pt3D.z) + { + noseClusterId = clusterId; + nosePoint = nearestPoint; + } + } } } if (noseClusterId < 0) @@ -544,29 +608,7 @@ SSX_planeInfo wd_planeLocalization( *errCode = SX_ERR_NOSEPOINT_FAIL; return planePoseInfo; } - //ǵ - SVzNL3DPosition nosePoint; - nosePoint.nPointIdx = 0; - nosePoint.pt3D = { 0.0, 0.0, 0.0 }; - for (int i = 0; i < (int)objClusters[noseClusterId].size(); i++) - { - if (nosePoint.pt3D.z < 1e-4) - nosePoint = objClusters[noseClusterId][i]; - else if(nosePoint.pt3D.z > objClusters[noseClusterId][i].pt3D.z) - nosePoint = objClusters[noseClusterId][i]; - } - if (nosePoint.pt3D.z < 1e-4) - { - *errCode = SX_ERR_NOSEPOINT_FAIL; - return planePoseInfo; - } -#if _OUTPUT_DEBUG_DATA - { - int nose_lineIdx = nosePoint.nPointIdx >> 16; - int nose_ptIdx = nosePoint.nPointIdx & 0xffff; - debugData[nose_lineIdx][nose_ptIdx].nPointIdx |= 0x10000; //ǵ - } -#endif + //̬ //жϻڵijȣԻǸ߶Ϊ׼ȡ߶ȷΧڵĵ㣬㳤 SVzNLRangeD bodyHRange = { nosePoint.pt3D.y + bodyRangeToNose.min, nosePoint.pt3D.y + bodyRangeToNose.max }; @@ -603,6 +645,24 @@ SSX_planeInfo wd_planeLocalization( if (axis.y < 0) axis = { -axis.x, -axis.y }; + //centrodΪ׼㵽centroidԶĵΪǵ + double maxDistance = 0; + SVzNL3DPosition bestPoint; + for (int m = 0; m < (int)objClusters[noseClusterId].size(); m++) + { + if (objClusters[noseClusterId][m].pt3D.z < centroid.y) + { + double dist = sqrt(pow(objClusters[noseClusterId][m].pt3D.x - centroid.x, 2) + pow(objClusters[noseClusterId][m].pt3D.z - centroid.y, 2)); + if (maxDistance < dist) + { + maxDistance = dist; + bestPoint = objClusters[noseClusterId][m]; + } + } + } + if(maxDistance > 1e-4) //ǵ + nosePoint = bestPoint; + double dirAngle = atan(axis.x / axis.y) * 180.0 / PI; planePoseInfo.nosePoint = nosePoint.pt3D; planePoseInfo.axis = { axis.x, 0, axis.y }; @@ -612,6 +672,11 @@ SSX_planeInfo wd_planeLocalization( planePoseInfo.dirAngle_deg = dirAngle; //Ƕ #if _OUTPUT_DEBUG_DATA + { + int nose_lineIdx = nosePoint.nPointIdx >> 16; + int nose_ptIdx = nosePoint.nPointIdx & 0xffff; + debugData[nose_lineIdx][nose_ptIdx].nPointIdx |= 0x10000; //ǵ + } for(int m = 0; m <(int)XOZBodayData.size(); m ++) { int nose_lineIdx = XOZBodayData[m].nPointIdx >> 16; @@ -710,6 +775,11 @@ SSX_planeInfo wd_planeLocalization( rightEnginePoint = distanceValidData[rightEngineIdx][i]; } #if _OUTPUT_DEBUG_DATA + { + int nose_lineIdx = nosePoint.nPointIdx >> 16; + int nose_ptIdx = nosePoint.nPointIdx & 0xffff; + debugData[nose_lineIdx][nose_ptIdx].nPointIdx |= 0x10000; //ǵ + } { int nose_lineIdx = leftEnginePoint.nPointIdx >> 16; int nose_ptIdx = leftEnginePoint.nPointIdx & 0xffff;