diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Version.h b/App/WorkpieceHole/WorkpieceHoleApp/Version.h index 9ad434d3..1d222b9b 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Version.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Version.h @@ -5,8 +5,8 @@ #define WORKPIECEHOLE_APP_NAME "工件孔定位" // 版本字符串 -#define WORKPIECEHOLE_VERSION_STRING "1.2.2" -#define WORKPIECEHOLE_BUILD_STRING "2" +#define WORKPIECEHOLE_VERSION_STRING "1.2.3" +#define WORKPIECEHOLE_BUILD_STRING "1" #define WORKPIECEHOLE_FULL_VERSION_STRING "V" WORKPIECEHOLE_VERSION_STRING "_" WORKPIECEHOLE_BUILD_STRING // 构建日期 diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Version.md b/App/WorkpieceHole/WorkpieceHoleApp/Version.md index 0bdb987a..2650edbc 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Version.md +++ b/App/WorkpieceHole/WorkpieceHoleApp/Version.md @@ -1,5 +1,13 @@ +# 1.2.3 +## build_1 2026-07-16 +1. 更新算法 工件4,5歇着的情况 + # 1.2.2 -## build_1 2026-07-14 +## build_2 2026-07-16 +1. 重新调整了工件序号 +2. 增加正反工件的识别 + +## build_1 2026-07-16 1. 工件3和工件5 反了。 2. 每个工件有独立的工具参数调整 diff --git a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so index 5c8f53fb..01242c95 100644 Binary files a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so and b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so differ diff --git a/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h b/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h index 3f719fb7..5cf70527 100644 --- a/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h +++ b/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h @@ -114,14 +114,6 @@ typedef struct int idx; }SSG_intPair; -typedef struct -{ - int data_0; - int data_1; - double value1; - double value2; -}SSG_intPairRelationD; - typedef struct { int flag; diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll index cfff0457..af9c0935 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll and b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb index 0f61b9e0..80c5afa5 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb and b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.dll index 2ce25b28..64f54034 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.dll and b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.dll differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.pdb index f8921a42..58d733ec 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.pdb and b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/workpieceHolePositioning.pdb differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.dll index de720dd4..430a8352 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.dll and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.dll differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb index 35e79238..16455b6f 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.dll index 8e182fc1..03ef8273 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.dll and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.dll differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb index fc581d78..1e4f66f8 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb differ diff --git a/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp b/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp index a668473a..7b8ebee4 100644 --- a/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp +++ b/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp @@ -978,12 +978,17 @@ void _XOYprojection( int px1 = (int)((x1 - x_range.min) / scale + sideWidth); int py1 = (int)((y1 - y_range.min) / scale + sideWidth); //x轴 + double mx2 = a_hole.center.x - dirAngleLen * a_hole.x_dir.x; + double my2 = a_hole.center.y - dirAngleLen * a_hole.x_dir.y; + int mpx2 = (int)((mx2 - x_range.min) / scale + sideWidth); + int mpy2 = (int)((my2 - y_range.min) / scale + sideWidth); + double x2 = a_hole.center.x + dirAngleLen * a_hole.x_dir.x; double y2 = a_hole.center.y + dirAngleLen * a_hole.x_dir.y; int px2 = (int)((x2 - x_range.min) / scale + sideWidth); int py2 = (int)((y2 - y_range.min) / scale + sideWidth); rgb = { 255, 0, 0 }; //x轴用红色 - cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); + cv::line(img, cv::Point(mpx2, mpy2), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1); //y轴 x2 = a_hole.center.x + dirAngleLen * a_hole.y_dir.x; y2 = a_hole.center.y + dirAngleLen * a_hole.y_dir.y; @@ -1557,24 +1562,25 @@ void TuoPuFa_holePosition_test2(void) #endif } -#define TPF3_TEST_GROUP 7 +#define TPF3_TEST_GROUP 8 //拓普发工件孔定位(工件定位) -void TuoPuFa_holePosition_test3(void) +void TuoPuFa_holePosition_test4(void) { const char* dataPath[TPF3_TEST_GROUP] = { - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/1层/", //0 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/2层/", //1 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/3层/", //2 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/4层/", //3 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/5层/", //4 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/6层/", //5 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/7层/", //6 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/1层/", //0 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/2层/", //1 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/3层/", //2 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/4层/", //3 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/5层/", //4 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/6层/", //5 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/7层/", //6 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/B10歪/", //7 }; SVzNLRange fileIdx[TPF3_TEST_GROUP] = { {1,11}, {1, 10}, {1,10}, {1,10}, {1, 10}, - {1,10}, {1, 10}, + {1,10}, {1, 10}, {1, 10}, }; const char* ver = wd_workpieceHolePositioningVersion(); @@ -1617,7 +1623,7 @@ void TuoPuFa_holePosition_test3(void) #endif #if TEST_COMPUTE_HOLE - for (int grp = 0; grp < TPF3_TEST_GROUP; grp++) + for (int grp = 7; grp < TPF3_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 @@ -1701,7 +1707,7 @@ void TuoPuFa_holePosition_test3(void) sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx); double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; // - double angleDrawLen = 15; + double angleDrawLen = 30; double displayScale = 0.3; cv::String imgName(calibFile); _genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen); @@ -1710,25 +1716,26 @@ void TuoPuFa_holePosition_test3(void) } #endif } -#define TPF4_TEST_GROUP 7 +#define TPF4_TEST_GROUP 8 //拓普发工件孔定位(工件定位) -void TuoPuFa_holePosition_test4(void) +void TuoPuFa_holePosition_test5(void) { const char* dataPath[TPF4_TEST_GROUP] = { - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/1层/", //0 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/2层/", //1 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/3层/", //2 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/4层/", //3 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/5层/", //4 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/6层/", //5 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/7层/", //6 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/1层/", //0 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/2层/", //1 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/3层/", //2 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/4层/", //3 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/5层/", //4 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/6层/", //5 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/7层/", //6 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/B20歪/", //7 }; SVzNLRange fileIdx[TPF4_TEST_GROUP] = { {1,11}, {1, 11}, {1,11}, {1,10}, {1, 10}, - {1,10}, {1, 10}, + {1,10}, {1, 10}, {1, 10}, }; const char* ver = wd_workpieceHolePositioningVersion(); @@ -1771,7 +1778,7 @@ void TuoPuFa_holePosition_test4(void) #endif #if TEST_COMPUTE_HOLE - for (int grp = 0; grp < TPF4_TEST_GROUP; grp++) + for (int grp = 7; grp < TPF4_TEST_GROUP; grp++) { SSG_planeCalibPara groundCalibPara; //初始化成单位阵 @@ -1855,7 +1862,7 @@ void TuoPuFa_holePosition_test4(void) sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx); double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; // - double angleDrawLen = 15; + double angleDrawLen = 30; double displayScale = 0.3; cv::String imgName(calibFile); _genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen); @@ -1867,28 +1874,28 @@ void TuoPuFa_holePosition_test4(void) #define TPF5_TEST_GROUP 14 //拓普发工件孔定位(工件定位) -void TuoPuFa_holePosition_test5(void) +void TuoPuFa_holePosition_test3(void) { const char* dataPath[TPF5_TEST_GROUP] = { - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/1层/", //0 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/2层/", //1 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/3层/", //2 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/4层/", //3 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/5层/", //4 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/6层/", //5 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/7层/", //6 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/8层/", //7 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/9层/", //8 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/10层/", //9 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/11层/", //10 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/12层/", //11 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/13层/", //12 - "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/14层/", //13 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/1层/", //0 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/2层/", //1 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/3层/", //2 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/4层/", //3 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/5层/", //4 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/6层/", //5 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/7层/", //6 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/8层/", //7 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/9层/", //8 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/10层/", //9 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/11层/", //10 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/12层/", //11 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/13层/", //12 + "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/14层/", //13 }; SVzNLRange fileIdx[TPF5_TEST_GROUP] = { - {1,10}, {1, 10}, {1,10}, {1,10}, {1, 10}, + {1,12}, {1, 10}, {1,10}, {1,10}, {1, 10}, {1,11}, {1, 10}, {1,11}, {1,10}, {1,10}, {1, 10}, {1,10}, {1,11}, {1,10} }; @@ -2742,9 +2749,9 @@ int main() { //TuoPuFa_holePosition_test(); //TuoPuFa_holePosition_test2(); - TuoPuFa_holePosition_test3(); + //TuoPuFa_holePosition_test3(); TuoPuFa_holePosition_test4(); - //TuoPuFa_holePosition_test5(); + TuoPuFa_holePosition_test5(); } else if (keSG_华航孔定位 == testMode) HuaHang_holePosition_test(); diff --git a/AppUtils/AppConfig/Inc/ConfigXmlUtils.h b/AppUtils/AppConfig/Inc/ConfigXmlUtils.h index c382d2b0..8aa6b8b4 100644 --- a/AppUtils/AppConfig/Inc/ConfigXmlUtils.h +++ b/AppUtils/AppConfig/Inc/ConfigXmlUtils.h @@ -29,10 +29,12 @@ namespace ConfigXmlUtils * @param root XML 根节点 * @param list 输出的矩阵列表 * @param defaultEulerOrder 当 XML 中无 eulerOrder 属性时使用的默认值 + * @param defaultCalibType 当 XML 中无 calibType 属性时使用的默认值(0=眼在手外,1=眼在手上) */ void LoadHandEyeCalibMatrixs(tinyxml2::XMLElement* root, std::vector& list, - int defaultEulerOrder = 11); + int defaultEulerOrder = 11, + int defaultCalibType = 0); /** * @brief 保存手眼标定矩阵列表到 XML 根节点( 格式) diff --git a/AppUtils/AppConfig/Inc/VrHandEyeCalibConfig.h b/AppUtils/AppConfig/Inc/VrHandEyeCalibConfig.h index c0b0649e..3c9c3d7e 100644 --- a/AppUtils/AppConfig/Inc/VrHandEyeCalibConfig.h +++ b/AppUtils/AppConfig/Inc/VrHandEyeCalibConfig.h @@ -16,6 +16,7 @@ struct VrHandEyeCalibMatrix { int cameraIndex; + int calibType; // 0=眼在手外,1=眼在手上 double matrix[16]; int eulerOrder; double rotX; @@ -35,6 +36,7 @@ struct VrHandEyeCalibMatrix VrHandEyeCalibMatrix() : cameraIndex(1) + , calibType(0) , eulerOrder(11) , rotX(0.0) , rotY(0.0) diff --git a/AppUtils/AppConfig/Src/ConfigXmlUtils.cpp b/AppUtils/AppConfig/Src/ConfigXmlUtils.cpp index 5bb36606..62d95965 100644 --- a/AppUtils/AppConfig/Src/ConfigXmlUtils.cpp +++ b/AppUtils/AppConfig/Src/ConfigXmlUtils.cpp @@ -12,11 +12,22 @@ namespace ConfigXmlUtils static void LoadSingleHandEyeCalibMatrix(XMLElement* handEyeElement, VrHandEyeCalibMatrix& calibMatrix, - int defaultEulerOrder) + int defaultEulerOrder, + int defaultCalibType) { if (handEyeElement->Attribute("cameraIndex")) calibMatrix.cameraIndex = handEyeElement->IntAttribute("cameraIndex"); + const int fallbackCalibType = defaultCalibType == 1 ? 1 : 0; + if (handEyeElement->Attribute("calibType")) { + const int calibType = handEyeElement->IntAttribute("calibType"); + calibMatrix.calibType = (calibType == 0 || calibType == 1) + ? calibType + : fallbackCalibType; + } else { + calibMatrix.calibType = fallbackCalibType; + } + for (int i = 0; i < 16; i++) { char attrName[32]; @@ -60,7 +71,8 @@ static void LoadSingleHandEyeCalibMatrix(XMLElement* handEyeElement, void LoadHandEyeCalibMatrixs(XMLElement* root, std::vector& list, - int defaultEulerOrder) + int defaultEulerOrder, + int defaultCalibType) { // 优先找 XMLElement* containerElement = root->FirstChildElement("HandEyeCalibMatrixs"); @@ -76,7 +88,8 @@ void LoadHandEyeCalibMatrixs(XMLElement* root, { VrHandEyeCalibMatrix calibMatrix; calibMatrix.cameraIndex = static_cast(list.size()) + 1; // 默认递增 - LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, defaultEulerOrder); + LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, + defaultEulerOrder, defaultCalibType); list.push_back(calibMatrix); handEyeElement = handEyeElement->NextSiblingElement("HandEyeCalibMatrix"); } @@ -89,7 +102,8 @@ void LoadHandEyeCalibMatrixs(XMLElement* root, { VrHandEyeCalibMatrix calibMatrix; calibMatrix.cameraIndex = 1; - LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, defaultEulerOrder); + LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, + defaultEulerOrder, defaultCalibType); list.push_back(calibMatrix); } } @@ -104,6 +118,7 @@ void SaveHandEyeCalibMatrixs(XMLDocument& doc, { XMLElement* handEyeElement = doc.NewElement("HandEyeCalibMatrix"); handEyeElement->SetAttribute("cameraIndex", calibMatrix.cameraIndex); + handEyeElement->SetAttribute("calibType", calibMatrix.calibType); for (int i = 0; i < 16; i++) { char attrName[32]; diff --git a/AppUtils/UICommon/HandEyeCalibWidget.ui b/AppUtils/UICommon/HandEyeCalibWidget.ui index 0519c481..2f5a7d94 100644 --- a/AppUtils/UICommon/HandEyeCalibWidget.ui +++ b/AppUtils/UICommon/HandEyeCalibWidget.ui @@ -57,6 +57,26 @@ padding: 2px; + + + + + + + 120 + 0 + + + + 标定方式: + + + + + + + + diff --git a/AppUtils/UICommon/Inc/HandEyeCalibWidget.h b/AppUtils/UICommon/Inc/HandEyeCalibWidget.h index 177009ab..778b27ae 100644 --- a/AppUtils/UICommon/Inc/HandEyeCalibWidget.h +++ b/AppUtils/UICommon/Inc/HandEyeCalibWidget.h @@ -30,6 +30,7 @@ struct HandEyeCalibCameraInfo struct HandEyeCalibData { int cameraIndex = 0; + int calibType = 0; // 0=眼在手外,1=眼在手上 double matrix[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, @@ -72,6 +73,23 @@ public: */ void setCalibData(int cameraIndex, const double matrix[16], bool isCalibrated); + /** + * @brief 设置新增相机数据使用的默认标定类型 + * @param calibType 0=眼在手外,1=眼在手上 + */ + void setDefaultCalibType(int calibType); + + /** + * @brief 设置指定相机的标定类型 + */ + void setCalibType(int cameraIndex, int calibType); + + /** + * @brief 获取指定相机的标定类型 + * @return 是否存在该相机的数据 + */ + bool getCalibType(int cameraIndex, int& outCalibType) const; + /** * @brief 设置指定相机的欧拉角顺序与补偿旋转 */ @@ -165,6 +183,7 @@ signals: private slots: void onCameraSelectionChanged(int index); + void onCalibTypeChanged(int index); void onLoadCalibMatrixClicked(); void onSaveCalibMatrixClicked(); @@ -174,6 +193,7 @@ private: void clearMatrix(); void displayIdentityMatrix(); void updateCalibStatus(bool isCalibrated); + void updateCalibType(int calibType); // 从矩阵编辑框读取当前矩阵值 bool readMatrixFromUI(double outMatrix[16]) const; @@ -187,6 +207,7 @@ private: Ui::HandEyeCalibWidget* ui = nullptr; QComboBox* m_comboCamera; + QComboBox* m_comboCalibType; QLabel* m_labelStatus; QLineEdit* m_matrixEdits[4][4]; // 4x4 矩阵编辑框 QPushButton* m_btnLoad; @@ -195,6 +216,7 @@ private: QVector m_calibDataCache; // 按相机索引缓存 QString m_defaultFilePath; bool m_matrixEditable; + int m_defaultCalibType; }; #endif // HANDEYECALIBWIDGET_H diff --git a/AppUtils/UICommon/Src/HandEyeCalibWidget.cpp b/AppUtils/UICommon/Src/HandEyeCalibWidget.cpp index df5ce4c5..cc976f02 100644 --- a/AppUtils/UICommon/Src/HandEyeCalibWidget.cpp +++ b/AppUtils/UICommon/Src/HandEyeCalibWidget.cpp @@ -12,10 +12,12 @@ HandEyeCalibWidget::HandEyeCalibWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::HandEyeCalibWidget) , m_comboCamera(nullptr) + , m_comboCalibType(nullptr) , m_labelStatus(nullptr) , m_btnLoad(nullptr) , m_btnSave(nullptr) , m_matrixEditable(false) + , m_defaultCalibType(0) { memset(m_matrixEdits, 0, sizeof(m_matrixEdits)); setupUI(); @@ -62,6 +64,38 @@ void HandEyeCalibWidget::setCalibData(int cameraIndex, const double matrix[16], } } +void HandEyeCalibWidget::setDefaultCalibType(int calibType) +{ + m_defaultCalibType = (calibType == 1) ? 1 : 0; + + const int cameraIndex = currentCameraIndex(); + const HandEyeCalibData* data = findCalibData(cameraIndex); + if (!data) { + updateCalibType(m_defaultCalibType); + } +} + +void HandEyeCalibWidget::setCalibType(int cameraIndex, int calibType) +{ + HandEyeCalibData& data = ensureCalibData(cameraIndex); + data.calibType = (calibType == 1) ? 1 : 0; + + if (currentCameraIndex() == cameraIndex) { + updateCalibType(data.calibType); + } +} + +bool HandEyeCalibWidget::getCalibType(int cameraIndex, int& outCalibType) const +{ + const HandEyeCalibData* data = findCalibData(cameraIndex); + if (!data) { + return false; + } + + outCalibType = data->calibType; + return true; +} + void HandEyeCalibWidget::setExtrinsicData(int cameraIndex, int eulerOrder, double rotX, double rotY, double rotZ) { @@ -214,13 +248,16 @@ void HandEyeCalibWidget::onCameraSelectionChanged(int index) if (index < 0 || !m_comboCamera || m_comboCamera->count() == 0) { m_btnLoad->setEnabled(false); m_btnSave->setEnabled(false); + m_comboCalibType->setEnabled(false); displayIdentityMatrix(); updateCalibStatus(false); + updateCalibType(m_defaultCalibType); return; } m_btnLoad->setEnabled(true); m_btnSave->setEnabled(true); + m_comboCalibType->setEnabled(true); int camIdx = m_comboCamera->itemData(index).toInt(); const HandEyeCalibData* data = findCalibData(camIdx); @@ -231,7 +268,22 @@ void HandEyeCalibWidget::onCameraSelectionChanged(int index) displayIdentityMatrix(); updateCalibStatus(false); } + updateCalibType(data ? data->calibType : m_defaultCalibType); +} +void HandEyeCalibWidget::onCalibTypeChanged(int index) +{ + if (index < 0 || !m_comboCalibType) { + return; + } + + const int cameraIndex = currentCameraIndex(); + if (cameraIndex < 0) { + return; + } + + HandEyeCalibData& data = ensureCalibData(cameraIndex); + data.calibType = (m_comboCalibType->itemData(index).toInt() == 1) ? 1 : 0; } void HandEyeCalibWidget::onLoadCalibMatrixClicked() @@ -254,6 +306,11 @@ void HandEyeCalibWidget::onLoadCalibMatrixClicked() settings.setIniCodec("UTF-8"); settings.beginGroup("CalibMatrixInfo_0"); + int calibType = settings.value("eCalibType", m_defaultCalibType).toInt(); + if (calibType != 0 && calibType != 1) { + calibType = m_defaultCalibType; + } + double matrix[16]; for (int i = 0; i < 16; ++i) { int row = i / 4; @@ -264,6 +321,7 @@ void HandEyeCalibWidget::onLoadCalibMatrixClicked() settings.endGroup(); setCalibData(camIdx, matrix, true); + setCalibType(camIdx, calibType); emit calibMatrixLoaded(camIdx, matrix); } @@ -322,10 +380,15 @@ void HandEyeCalibWidget::setupUI() matrixFont.setPointSize(16); m_comboCamera = ui->comboCamera; + m_comboCalibType = ui->comboCalibType; m_labelStatus = ui->labelStatus; m_btnLoad = ui->btnLoad; m_btnSave = ui->btnSave; + m_comboCalibType->addItem(QStringLiteral("眼在手外"), 0); + m_comboCalibType->addItem(QStringLiteral("眼在手上"), 1); + updateCalibType(m_defaultCalibType); + m_matrixEdits[0][0] = ui->editMatrix00; m_matrixEdits[0][1] = ui->editMatrix01; m_matrixEdits[0][2] = ui->editMatrix02; @@ -363,6 +426,8 @@ void HandEyeCalibWidget::setupUI() connect(m_comboCamera, static_cast(&QComboBox::currentIndexChanged), this, &HandEyeCalibWidget::onCameraSelectionChanged); + connect(m_comboCalibType, static_cast(&QComboBox::currentIndexChanged), + this, &HandEyeCalibWidget::onCalibTypeChanged); connect(m_btnLoad, &QPushButton::clicked, this, &HandEyeCalibWidget::onLoadCalibMatrixClicked); connect(m_btnSave, &QPushButton::clicked, @@ -411,6 +476,18 @@ void HandEyeCalibWidget::updateCalibStatus(bool isCalibrated) } } +void HandEyeCalibWidget::updateCalibType(int calibType) +{ + if (!m_comboCalibType) { + return; + } + + const int index = m_comboCalibType->findData(calibType == 1 ? 1 : 0); + m_comboCalibType->blockSignals(true); + m_comboCalibType->setCurrentIndex(index); + m_comboCalibType->blockSignals(false); +} + bool HandEyeCalibWidget::readMatrixFromUI(double outMatrix[16]) const { for (int r = 0; r < 4; ++r) { @@ -455,6 +532,7 @@ HandEyeCalibData& HandEyeCalibWidget::ensureCalibData(int cameraIndex) HandEyeCalibData newData; newData.cameraIndex = cameraIndex; + newData.calibType = m_defaultCalibType; m_calibDataCache.append(newData); return m_calibDataCache.last(); }