diff --git a/App/RodAndBarPosition/Doc/MODBUS_PROTOCOL.md b/App/RodAndBarPosition/Doc/MODBUS_PROTOCOL.md index 14741471..207e4aff 100644 --- a/App/RodAndBarPosition/Doc/MODBUS_PROTOCOL.md +++ b/App/RodAndBarPosition/Doc/MODBUS_PROTOCOL.md @@ -46,6 +46,7 @@ | 1 | 成功(地址 2~13 数据有效) | | 2 | 检测失败 | | 3 | 结果为空 / 无更多缓存结果 | +| 4 | 料框为空(算法返回 SX_ERR_ZERO_OBJECTS = -1010,未检出任何棒材) | ## 5. 通信流程 @@ -59,7 +60,7 @@ ### 5.2 读取结果 1. 检测完成后,视觉系统写入: - - 地址 1:状态码(1=成功,2=失败,3=空结果) + - 地址 1:状态码(1=成功,2=失败,3=空结果,4=料框为空) - 地址 2~13:第一个棒材的 X, Y, Z, Roll, Pitch, Yaw(仅状态码为 1 时有效) 2. 外部客户端轮询地址 1,当值从 0 变为非零时表示检测完成 3. 状态码为 1 时,读取地址 2~13 获取定位结果 diff --git a/App/RodAndBarPosition/Doc/modbus_client.mthings b/App/RodAndBarPosition/Doc/modbus_client.mthings deleted file mode 100644 index fae600be..00000000 --- a/App/RodAndBarPosition/Doc/modbus_client.mthings +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/RodAndBarPositionPresenter.cpp b/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/RodAndBarPositionPresenter.cpp index 764e4890..70d98b9a 100644 --- a/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/RodAndBarPositionPresenter.cpp +++ b/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/RodAndBarPositionPresenter.cpp @@ -224,6 +224,27 @@ int RodAndBarPositionPresenter::ProcessAlgoDetection(std::vector()) { + pStatus->OnStatusUpdate("料框为空,未检测到棒材"); + } + if (IsModbusServerRunning()) { + uint16_t statusCode = 4; // 4 = 料框为空(SX_ERR_ZERO_OBJECTS) + WriteModbusRegisters(1, &statusCode, 1); + } + { + std::lock_guard lock(m_resultCacheMutex); + m_lastDetectionResult = DetectionResult{}; + m_resultIndex = 0; + } + SetWorkStatus(WorkStatus::Completed); + SetWorkStatus(WorkStatus::Ready); + return SUCCESS; + } + // 根据项目类型选择处理方式 if (GetStatusCallback()) { QString err = QString("错误:%1").arg(nRet); @@ -680,7 +701,7 @@ void RodAndBarPositionPresenter::_SendDetectionResultToModbus(const DetectionRes ConfigResult configResult = m_pConfigManager->GetConfigResult(); bool bigEndian = (configResult.byteOrder == 0); // 0=大端序, 1=小端序 - // 地址 1:状态码(0=正在检测,1=成功,2=失败,3=结果为空/无更多结果) + // 地址 1:状态码(0=正在检测,1=成功,2=失败,3=结果为空/无更多结果,4=料框为空) uint16_t statusCode = 1; // 默认成功 if (!result.success) { statusCode = 2; // 检测失败 diff --git a/App/RodAndBarPosition/RodAndBarPositionApp/Version.h b/App/RodAndBarPosition/RodAndBarPositionApp/Version.h index 7e89dbde..93d7ec59 100644 --- a/App/RodAndBarPosition/RodAndBarPositionApp/Version.h +++ b/App/RodAndBarPosition/RodAndBarPositionApp/Version.h @@ -5,7 +5,7 @@ // 应用名称 #define RODANDBARPOSITION_APP_NAME "棒材定位" -#define RODANDBARPOSITION_VERSION_STRING "1.1.0" +#define RODANDBARPOSITION_VERSION_STRING "1.1.1" #define RODANDBARPOSITION_BUILD_STRING "1" #define RODANDBARPOSITION_FULL_VERSION_STRING "V" RODANDBARPOSITION_VERSION_STRING "_" RODANDBARPOSITION_BUILD_STRING diff --git a/App/RodAndBarPosition/RodAndBarPositionApp/Version.md b/App/RodAndBarPosition/RodAndBarPositionApp/Version.md index 4561ae86..ad0d52f0 100644 --- a/App/RodAndBarPosition/RodAndBarPositionApp/Version.md +++ b/App/RodAndBarPosition/RodAndBarPositionApp/Version.md @@ -1,3 +1,7 @@ +# 1.1.1 2026-045-26 +## build_1 +1. 更新算法1.3.2 + # 1.1.0 2026-04-13 ## build_1 1. 更新内存泄露问题 diff --git a/AppAlgo/rodAndBarDetection/Arm/aarch64/librodAndBarDetection.so b/AppAlgo/rodAndBarDetection/Arm/aarch64/librodAndBarDetection.so index 1316cb87..29b787b4 100644 Binary files a/AppAlgo/rodAndBarDetection/Arm/aarch64/librodAndBarDetection.so and b/AppAlgo/rodAndBarDetection/Arm/aarch64/librodAndBarDetection.so differ diff --git a/AppAlgo/rodAndBarDetection/Inc/rodAndBarDetection_Export.h b/AppAlgo/rodAndBarDetection/Inc/rodAndBarDetection_Export.h index 68dbda39..139d604b 100644 --- a/AppAlgo/rodAndBarDetection/Inc/rodAndBarDetection_Export.h +++ b/AppAlgo/rodAndBarDetection/Inc/rodAndBarDetection_Export.h @@ -65,7 +65,7 @@ SG_APISHARED_EXPORT const char* wd_rodAndBarDetectionVersion(void); SG_APISHARED_EXPORT SSG_planeCalibPara sx_rodPosition_getBaseCalibPara( std::vector< std::vector>& scanLines); -#if 0 +#if 1 //̬ƽȥ SG_APISHARED_EXPORT void sx_rodPosition_lineDataR( std::vector< SVzNL3DPosition>& a_line, diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.dll b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.dll index 4bf74dc5..96a4419b 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.dll and b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.dll differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.pdb b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.pdb index 7bd78d3b..f1eefa5e 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.pdb and b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/baseAlgorithm.pdb differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.dll b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.dll index 25ccd1ca..311a93e5 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.dll and b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.dll differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.lib b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.lib index 3b90d409..289b0fdf 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.lib and b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.lib differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.pdb b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.pdb index 5c46a95f..064ec078 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.pdb and b/AppAlgo/rodAndBarDetection/Windows/x64/Debug/rodAndBarDetection.pdb differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.dll b/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.dll index 689ad0c6..65048b5f 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.dll and b/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.dll differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.pdb b/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.pdb index 7b799150..fd7a37b7 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.pdb and b/AppAlgo/rodAndBarDetection/Windows/x64/Release/baseAlgorithm.pdb differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.dll b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.dll index 809359e1..441cc0d5 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.dll and b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.dll differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.lib b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.lib index 2821b542..dc70572e 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.lib and b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.lib differ diff --git a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.pdb b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.pdb index ea835191..7fabaf1a 100644 Binary files a/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.pdb and b/AppAlgo/rodAndBarDetection/Windows/x64/Release/rodAndBarDetection.pdb differ diff --git a/AppAlgo/rodAndBarDetection/rodAndBarDetection_test.cpp b/AppAlgo/rodAndBarDetection/rodAndBarDetection_test.cpp index 669351b4..d79c59c1 100644 --- a/AppAlgo/rodAndBarDetection/rodAndBarDetection_test.cpp +++ b/AppAlgo/rodAndBarDetection/rodAndBarDetection_test.cpp @@ -13,6 +13,7 @@ #include #include +#include typedef struct { int r; @@ -31,6 +32,101 @@ typedef struct float b; } SPointXYZRGB; + +// 点乘 dot +double _dotMultiply(const SVzNL3DPoint& a, const SVzNL3DPoint& b) +{ + return (a.x * b.x + a.y * b.y + a.z * b.z); +} + +// 模长 +double _length(const SVzNL3DPoint& a) +{ + return sqrt(a.x * a.x + a.y * a.y + a.z * a.z); +} + +// 计算两个向量夹角(返回 角度) +float _computeVecAngle(const SVzNL3DPoint& a, const SVzNL3DPoint& b) +{ + float l = _length(a) * _length(b); + if (l < 1e-6f) + return 0.0f; // 避免除零 + + float cosTheta = _dotMultiply(a, b) / l; + cosTheta = cosTheta > 1.0 ? 1.0 : cosTheta; + cosTheta = cosTheta < -1.0 ? -1.0 : cosTheta; + float rad = acosf(cosTheta); + float degree = rad * 180.0f / (float)M_PI; + return degree; +} + +void _outputCalibPara(char* fileName, SSG_planeCalibPara calibPara) +{ + std::ofstream sw(fileName); + char dataStr[250]; + //调平矩阵 + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[0], calibPara.planeCalib[1], calibPara.planeCalib[2]); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[3], calibPara.planeCalib[4], calibPara.planeCalib[5]); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[6], calibPara.planeCalib[7], calibPara.planeCalib[8]); + sw << dataStr << std::endl; + //地面高度 + sprintf_s(dataStr, 250, "%g", calibPara.planeHeight); + sw << dataStr << std::endl; + //反向旋转矩阵 + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[0], calibPara.invRMatrix[1], calibPara.invRMatrix[2]); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[3], calibPara.invRMatrix[4], calibPara.invRMatrix[5]); + sw << dataStr << std::endl; + sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[6], calibPara.invRMatrix[7], calibPara.invRMatrix[8]); + sw << dataStr << std::endl; + + sw.close(); +} + +SSG_planeCalibPara _readCalibPara(char* fileName) +{ + //设置初始结果 + double initCalib[9] = { + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 }; + SSG_planeCalibPara planePara; + for (int i = 0; i < 9; i++) + planePara.planeCalib[i] = initCalib[i]; + planePara.planeHeight = -1.0; + for (int i = 0; i < 9; i++) + planePara.invRMatrix[i] = initCalib[i]; + + std::ifstream inputFile(fileName); + std::string linedata; + + if (inputFile.is_open() == false) + return planePara; + + //调平矩阵 + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[0], &planePara.planeCalib[1], &planePara.planeCalib[2]); + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[3], &planePara.planeCalib[4], &planePara.planeCalib[5]); + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[6], &planePara.planeCalib[7], &planePara.planeCalib[8]); + //地面高度 + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf", &planePara.planeHeight); + //反向旋转矩阵 + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[0], &planePara.invRMatrix[1], &planePara.invRMatrix[2]); + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[3], &planePara.invRMatrix[4], &planePara.invRMatrix[5]); + std::getline(inputFile, linedata); + sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[6], &planePara.invRMatrix[7], &planePara.invRMatrix[8]); + + inputFile.close(); + return planePara; +} + void wdReadLaserScanPointFromFile_XYZ_vector(const char* fileName, std::vector>& scanData) { std::ifstream inputFile(fileName); @@ -165,49 +261,38 @@ void _outputScanDataFile(char* fileName, std::vector& rodParas) { - //设置初始结果 - double initCalib[9] = { - 1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0 }; - SSG_planeCalibPara planePara; - for (int i = 0; i < 9; i++) - planePara.planeCalib[i] = initCalib[i]; - planePara.planeHeight = -1.0; - for (int i = 0; i < 9; i++) - planePara.invRMatrix[i] = initCalib[i]; - std::ifstream inputFile(fileName); std::string linedata; if (inputFile.is_open() == false) - return planePara; + return; - //调平矩阵 - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[0], &planePara.planeCalib[1], &planePara.planeCalib[2]); - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[3], &planePara.planeCalib[4], &planePara.planeCalib[5]); - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[6], &planePara.planeCalib[7], &planePara.planeCalib[8]); - //地面高度 - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf", &planePara.planeHeight); - //反向旋转矩阵 - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[0], &planePara.invRMatrix[1], &planePara.invRMatrix[2]); - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[3], &planePara.invRMatrix[4], &planePara.invRMatrix[5]); - std::getline(inputFile, linedata); - sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[6], &planePara.invRMatrix[7], &planePara.invRMatrix[8]); - - inputFile.close(); - return planePara; + std::vector indices; + int maxIdx = 0; + std::vector< SSX_rodParam> paras; + while (getline(inputFile, linedata)) + { + int idx; + float len, dia; + sscanf_s(linedata.c_str(), "%d_L_%f_D_%f", &idx, &len, &dia); + SSX_rodParam a_para = { dia , len }; + indices.push_back(idx); + paras.push_back(a_para); + maxIdx = maxIdx < idx ? idx : maxIdx; + } + if (maxIdx == 0) + return; + rodParas.resize(maxIdx + 1); + for (int i = 0; i < (int)indices.size(); i++) + { + int idx = indices[i]; + rodParas[idx] = paras[i]; + } + return; } - void _outputChanneltInfo(char* fileName, std::vector& screwInfo) { std::ofstream sw(fileName); @@ -450,15 +535,15 @@ void _outputRGBDScan_RGBD_centerPose( SVzNL3DPosition* pt3D = &scanLines[line][i]; if (pt3D->nPointIdx == 2) + { + rgb = { 135,206,235 }; + size = 5; + } + else if (pt3D->nPointIdx == 3) { rgb = { 250, 0, 0 }; size = 5; } - //else if (pt3D->nPointIdx == 1) - //{ - // rgb = { 0, 0, 250 }; - // size = 3; - //} else //if (pt3D->nPointIdx == 0) { rgb = { 200, 200, 200 }; @@ -500,7 +585,7 @@ void _outputRGBDScan_RGBD_centerPose( //输出法向 size = 1; - double len = 60; + double len = 110; lineIdx = 0; { SVzNL3DPoint pt0 = { poseInfo.center.x, // - len * poseInfo.normalDir.x, @@ -878,7 +963,7 @@ void _outputRGBDScan_RGBD_weldSeam( sw.close(); } -#define SCREW_TEST_GROUP 7 +#define SCREW_TEST_GROUP 10 void screwTest(void) { const char* dataPath[SCREW_TEST_GROUP] = { @@ -889,17 +974,22 @@ void screwTest(void) "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2/", //4 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2未动螺杆拧进去100mm左右/", //5 "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云4/位置2向前100mm螺杆拧进去100mm左右/", //6 + "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/另一根螺杆/", //7 + "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/拍照点1/", //8 + "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/螺杆点云20260621/拍照点1xyz移动10mm/", //9 + }; SVzNLRange fileIdx[SCREW_TEST_GROUP] = { {1,4},{1,30},{1,11}, - {1,20}, {1,20}, {1,5}, {1,21} + {1,20}, {1,20}, {1,5}, {1,21}, + {1,10}, {1,10}, {1,10} }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); - for (int grp = 3; grp < SCREW_TEST_GROUP; grp++) + for (int grp = 9; grp < SCREW_TEST_GROUP; grp++) { for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { @@ -908,6 +998,8 @@ void screwTest(void) if(0 == grp) sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); + else if( (grp>= 7)&&(grp <= 9)) + sprintf_s(_scan_file, "%sLaserline_%d.txt", dataPath[grp], fidx); else sprintf_s(_scan_file, "%s%d_LaserData_Jl26C299.txt", dataPath[grp], fidx); @@ -962,12 +1054,23 @@ void screwTest(void) &errCode); long t2 = (long)GetTickCount64(); - printf("%s: %d(ms), errCode=%d\n", _scan_file, (int)(t2 - t1), errCode); + //输出测试结果 - sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); - _outputRGBDScan_RGBD(_scan_file, scanLines, screwInfo); - sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); - _outputChanneltInfo(_scan_file, screwInfo); + char _out_file[256]; + sprintf_s(_out_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); + _outputRGBDScan_RGBD(_out_file, scanLines, screwInfo); + sprintf_s(_out_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); + _outputChanneltInfo(_out_file, screwInfo); + + if (screwInfo.size() > 0) + { + SVzNL3DPoint zAxis = { 0, 0, 1.0 }; + float angle = _computeVecAngle(screwInfo[0].axialDir, zAxis); + printf("%s: %d(ms), errCode=%d, {%f, %f, %f}, 与Z轴夹角=%f \n", _scan_file, (int)(t2 - t1), errCode, + (float)screwInfo[0].center.x, (float)screwInfo[0].center.y, (float)screwInfo[0].center.z, angle); + } + else + printf("%s: %d(ms), errCode=%d\n", _scan_file, (int)(t2 - t1), errCode); } } } @@ -975,7 +1078,7 @@ void screwTest(void) #define LOCATING_PALTE_TEST_GROUP 1 void locatingPlateTest(void) { - const char* dataPath[SCREW_TEST_GROUP] = { + const char* dataPath[LOCATING_PALTE_TEST_GROUP] = { "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/定位盘点云/", //0 }; @@ -1030,22 +1133,286 @@ void locatingPlateTest(void) } } -#define ROD_POSITION_TEST_GROUP 2 -void rodPositionTest(void) +#define NEW_LOCATING_PALTE_TEST_GROUP 1 +void newLocatingPlateTest(void) { - const char* dataPath[ROD_POSITION_TEST_GROUP] = { - "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/", //0 - "F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据/", //1 + const char* dataPath[NEW_LOCATING_PALTE_TEST_GROUP] = { + "F:/ShangGu/项目/冠钦项目/螺杆测量/配天现场点云/定位盘点云20260621/", //0 }; - SVzNLRange fileIdx[ROD_POSITION_TEST_GROUP] = { - {1,8}, {1,5} + SVzNLRange fileIdx[NEW_LOCATING_PALTE_TEST_GROUP] = { + {12,13}, }; const char* ver = wd_rodAndBarDetectionVersion(); printf("ver:%s\n", ver); - for (int grp = 1; grp < ROD_POSITION_TEST_GROUP; grp++) + for (int grp = 0; grp < NEW_LOCATING_PALTE_TEST_GROUP; grp++) + { + for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) + { + //fidx =2; + char _scan_file[256]; + sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); + + std::vector> scanLines; + wdReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); + + //转成plyTxt格式 + //sprintf_s(_scan_file, "%s%d_ply_Hi229229.txt", dataPath[grp], fidx); + //wdSavePlyTxt(_scan_file, scanLines); + + long t1 = (long)GetTickCount64();//统计时间 + + SSG_cornerParam cornerParam; + cornerParam.cornerTh = 45; //45度角 + cornerParam.scale = 5.0; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; + cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; + cornerParam.minEndingGap_z = 5.0; + cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平 + cornerParam.jumpCornerTh_2 = 60; + + int errCode = 0; + SSX_platePoseInfo centerPose = sx_getLocationPlatePose_new( + scanLines, + cornerParam, + &errCode); + + long t2 = (long)GetTickCount64(); + printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1), errCode); + //输出测试结果 + sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); + _outputRGBDScan_RGBD_centerPose(_scan_file, scanLines, centerPose); + sprintf_s(_scan_file, "%sresult\\%d_screw_info.txt", dataPath[grp], fidx); + _outputPlatePiseInfo(_scan_file, centerPose); + } + } +} + +; +void _removeNullData(std::vector>& scanLines, double _F, std::vector>& scanData) +{ + std::vector< SVzNLPointXYZRGBA> validPoints; + for (int line = 0; line < (int)scanLines.size(); line++) + { + for (int j = 0; j < (int)scanLines[line].size(); j++) + { + if (scanLines[line][j].pt3D.z > 1e-4) + { + SVzNLPointXYZRGBA a_pt; + double v = _F * scanLines[line][j].pt3D.y / scanLines[line][j].pt3D.z + 2000; + a_pt.nRGB = (int)(v + 0.5); + a_pt.x = scanLines[line][j].pt3D.x; + a_pt.y = scanLines[line][j].pt3D.y; + a_pt.z = scanLines[line][j].pt3D.z; + validPoints.push_back(a_pt); + } + } + } + + std::vector< SVzNLPointXYZRGBA> a_line; + SVzNLPointXYZRGBA pre_pt; + pre_pt.x = 0; + pre_pt.y = 0; + pre_pt.z = 0; + pre_pt.nRGB = -1; + for (int i = 0; i < validPoints.size(); i++) + { + if (validPoints[i].nRGB < (pre_pt.nRGB - 10)) + { + if (a_line.size() > 0) + scanData.push_back(a_line); + a_line.clear(); + } + a_line.push_back(validPoints[i]); + pre_pt = validPoints[i]; + } + if(a_line.size() > 0) + scanData.push_back(a_line); + return; +} +void _convertToGridData_XYZRGB(std::vector>& scanData, double _F, std::vector>& gridData) +{ + int lineNum = (int)scanData.size(); + int min_y = 100000000; + int max_y = -10000000; + int validStartLine = -1; + int validEndLine = -1; + for (int line = 0; line < lineNum; line++) + { + if (scanData[line].size() > 0) + { + if (validStartLine < 0) + { + validStartLine = line; + validEndLine = line; + } + else + validEndLine = line; + } + + for (int i = 0; i < (int)scanData[line].size(); i++) + { + SVzNLPointXYZRGBA& a_pt = scanData[line][i]; + if (a_pt.z > 1e-4) + { + double v = _F * a_pt.y / a_pt.z + 2000; + a_pt.nRGB = (int)(v + 0.5); + max_y = max_y < (int)a_pt.nRGB ? (int)a_pt.nRGB : max_y; + min_y = min_y > (int)a_pt.nRGB ? (int)a_pt.nRGB : min_y; + } + } + } + if (min_y == 100000000) + return; + + int vldLineNum = validEndLine - validStartLine + 1; + gridData.resize(vldLineNum); + int pt_counter = max_y - min_y + 1; + for (int i = 0; i < vldLineNum; i++) + { + gridData[i].resize(pt_counter); + for (int j = 0; j < pt_counter; j++) + { + gridData[i][j].nPointIdx = j; + gridData[i][j].pt3D.x = 0; + gridData[i][j].pt3D.y = 0; + gridData[i][j].pt3D.z = 0; + } + } + for (int line = validStartLine; line <= validEndLine; line++) + { + int gridLine = line - validStartLine; + for (int i = 0; i < (int)scanData[line].size(); i++) + { + SVzNLPointXYZRGBA& a_pt = scanData[line][i]; + if (a_pt.z > 1e-4) + { + int pt_id = a_pt.nRGB - min_y; + gridData[gridLine][pt_id].pt3D.x = a_pt.x; + gridData[gridLine][pt_id].pt3D.y = a_pt.y; + gridData[gridLine][pt_id].pt3D.z = a_pt.z; + } + } + } + return; +} + +#define ROD_POSITION_TEST_GROUP 5 +#define TEST_CONVERT_TO_GRID 0 +#define TEST_COMPUTE_CALIB_PARA 0 +#define TEST_COMPUTE_ROD_POSITION 1 +void rodPositionTest(void) +{ +#if TEST_CONVERT_TO_GRID + //将数据转换成栅格格式格式 + char _scan_dir[256]; + int lineNum = 0; + float lineV = 0.0f; + int dataCalib = 0; + int maxTimeStamp = 0; + int clockPerSecond = 0; + sprintf_s(_scan_dir, "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/"); + char _scan_src_file[256]; + double _F = 1219.15; //f + for (int i = 1; i <= 3; i++) + { + //read ply txt + sprintf_s(_scan_src_file, "%sLaserDataRAW_%d.txt", _scan_dir, i); + + std::vector> scanLines; + wdReadLaserScanPointFromFile_XYZ_vector(_scan_src_file, scanLines); + + std::vector> scanData; + _removeNullData(scanLines, _F, scanData); + + std::vector> gridData; + _convertToGridData_XYZRGB(scanData, _F, gridData); + char _out_file[256]; + sprintf_s(_out_file, "%sLaserData_%d.txt", _scan_dir, i); + _outputScanDataFile(_out_file, gridData, 0.0f, 0, 0); + + printf("%s: convert done!\n", _scan_src_file); + } + printf("all converted done!\n", _scan_src_file); +#endif +#if TEST_COMPUTE_CALIB_PARA + const char* calibDataPath = "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/调平/位置1/"; + char _calib_datafile[256]; + sprintf_s(_calib_datafile, "%sGroundData_1.txt", calibDataPath); + int lineNum = 0; + float lineV = 0.0f; + int dataCalib = 0; + int maxTimeStamp = 0; + int clockPerSecond = 0; + std::vector> scanData; + wdReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanData); + + lineNum = (int)scanData.size(); + if (scanData.size() > 0) + { + SSG_planeCalibPara calibPara = sx_rodPosition_getBaseCalibPara(scanData); + //结果进行验证 + for (int i = 0; i < lineNum; i++) + { + if (i == 14) + int kkk = 1; + //行处理 + //调平,去除地面 + sx_rodPosition_lineDataR(scanData[i], calibPara.planeCalib, -1); + } + // + char calibFile[250]; + sprintf_s(calibFile, "%sground_calib_para.txt", calibDataPath); + _outputCalibPara(calibFile, calibPara); + char _out_file[256]; + sprintf_s(_out_file, "%sGroundData_1_calib_verify.txt", calibDataPath); + + _outputScanDataFile(_out_file, scanData, lineV, maxTimeStamp, clockPerSecond); +#if 0 + for (int fidx = fileIdx[cvtGrp].nMin; fidx <= fileIdx[cvtGrp].nMax; fidx++) + { + //fidx =4; + char _scan_file[256]; + sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[cvtGrp], fidx); + std::vector> scanLines; + vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines); + if (scanLines.size() == 0) + continue; + lineNum = (int)scanLines.size(); + for (int i = 0; i < lineNum; i++) + { + //调平,去除地面 + wd_lineDataR(scanLines[i], calibPara.planeCalib, -1); + } + sprintf_s(_scan_file, "%sLaserData_%d_calib_verify.txt", dataPath[cvtGrp], fidx); + int headNullLines = 0; + _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); + } +#endif + printf("%s: calib done!\n", _calib_datafile); + } +#endif + +#if TEST_COMPUTE_ROD_POSITION + const char* dataPath[ROD_POSITION_TEST_GROUP] = { + "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/测试数据/", //0 + "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/空料框及内剩一根棒材/", //1 + "F:/ShangGu/项目/冠钦项目/矩森棒材抓取/其它尺寸棒材点云/", //2 + + "F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据/", //3 + "F:/ShangGu/项目/冠钦项目/胶布圆棒抓取/模拟测试数据2/", //4 + }; + + SVzNLRange fileIdx[ROD_POSITION_TEST_GROUP] = { + {1,8}, {1,3}, {1,31}, + {1,5},{1,11} + }; + + const char* ver = wd_rodAndBarDetectionVersion(); + printf("ver:%s\n", ver); + + for (int grp = 0; grp <= 2; grp++) { SSG_planeCalibPara poseCalibPara; //初始化成单位阵 @@ -1061,15 +1428,21 @@ void rodPositionTest(void) poseCalibPara.planeHeight = -1.0; for (int i = 0; i < 9; i++) poseCalibPara.invRMatrix[i] = poseCalibPara.planeCalib[i]; - //char calibFile[250]; - //sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); - //poseCalibPara = _readCalibPara(calibFile); + + char calibFile[250]; + sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]); + poseCalibPara = _readCalibPara(calibFile); + + sprintf_s(calibFile, "%sparameter.txt", dataPath[grp]); + std::vector rodParas; + if (grp <= 2) + _readRodParas(calibFile, rodParas); for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++) { - //fidx =1; + //fidx =5; char _scan_file[256]; - if(1 == grp) + if( (3 == grp) ||(4 == grp)) sprintf_s(_scan_file, "%s%d_LaserData_Hi229156.txt", dataPath[grp], fidx); else sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx); @@ -1084,10 +1457,9 @@ void rodPositionTest(void) long t1 = (long)GetTickCount64();//统计时间 SSX_rodParam rodParam; - if (0 == grp) + if (grp <= 2) { - rodParam.diameter = 52.0; //圆棒直径 - rodParam.len = 290; + rodParam = rodParas[fidx]; } else { @@ -1096,7 +1468,7 @@ void rodPositionTest(void) } SSG_cornerParam cornerParam; - cornerParam.cornerTh = 60; //45度角 + cornerParam.cornerTh = 45; //45度角 cornerParam.scale = rodParam.diameter / 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8; cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4; cornerParam.minEndingGap_z = 5.0; @@ -1112,8 +1484,8 @@ void rodPositionTest(void) growParam.yDeviation_max = 10.0; growParam.maxSkipDistance = 10.0; growParam.zDeviation_max = 10.0;// - growParam.minLTypeTreeLen = 100; //mm, 螺杆长度 - growParam.minVTypeTreeLen = 100; //mm + growParam.minLTypeTreeLen = rodParam.len * 0.75; //mm, 螺杆长度 + growParam.minVTypeTreeLen = rodParam.len * 0.75; //mm bool isHorizonScan = true; //true:激光线平行槽道;false:激光线垂直槽道 int errCode = 0; @@ -1129,7 +1501,7 @@ void rodPositionTest(void) &errCode); long t2 = (long)GetTickCount64(); - printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1)); + printf("%s: %d(ms),errCode=%d\n", _scan_file, (int)(t2 - t1),errCode); //输出测试结果 sprintf_s(_scan_file, "%sresult\\%d_result.txt", dataPath[grp], fidx); _outputRGBDScan_RGBD_rodInfo(_scan_file, scanLines, rodInfo); @@ -1137,6 +1509,7 @@ void rodPositionTest(void) _outputRodtInfo(_scan_file, rodInfo); } } +#endif } @@ -1239,21 +1612,35 @@ void rodWeldSeamPosition_test(void) } } + +typedef enum +{ + keSG_测试_配天螺杆定位 = 0, + keSG_测试_配天定位盘定位, + keSG_测试_配天新定位盘定位, + keSG_测试_棒材抓取, + keSG_测试_筑裕钢筋焊缝定位, +} ESG_testMode; + int main() { -#if 1 //螺杆定位测试 -#if 1 - screwTest(); -#else - locatingPlateTest(); -#endif -#else //棒材抓取定位测试 -#if 1 - rodPositionTest(); -#else - rodWeldSeamPosition_test(); -#endif -#endif + //ESG_testMode testMode = keSG_测试_配天螺杆定位; + //ESG_testMode testMode = keSG_测试_配天定位盘定位; + //ESG_testMode testMode = keSG_测试_配天新定位盘定位; + ESG_testMode testMode = keSG_测试_棒材抓取; + //ESG_testMode testMode = keSG_测试_筑裕钢筋焊缝定位; + + if(keSG_测试_配天螺杆定位 == testMode) + screwTest(); + else if(keSG_测试_配天定位盘定位 == testMode) + locatingPlateTest(); + else if (keSG_测试_配天新定位盘定位 == testMode) + newLocatingPlateTest(); + else if(keSG_测试_棒材抓取 == testMode) + rodPositionTest(); + else if(keSG_测试_筑裕钢筋焊缝定位 == testMode) + rodWeldSeamPosition_test(); + return 0; }