工件孔更新算法,斜着角度不对的问题
This commit is contained in:
parent
9926c9907e
commit
b15533e36e
@ -5,8 +5,8 @@
|
|||||||
#define WORKPIECEHOLE_APP_NAME "工件孔定位"
|
#define WORKPIECEHOLE_APP_NAME "工件孔定位"
|
||||||
|
|
||||||
// 版本字符串
|
// 版本字符串
|
||||||
#define WORKPIECEHOLE_VERSION_STRING "1.2.2"
|
#define WORKPIECEHOLE_VERSION_STRING "1.2.3"
|
||||||
#define WORKPIECEHOLE_BUILD_STRING "2"
|
#define WORKPIECEHOLE_BUILD_STRING "1"
|
||||||
#define WORKPIECEHOLE_FULL_VERSION_STRING "V" WORKPIECEHOLE_VERSION_STRING "_" WORKPIECEHOLE_BUILD_STRING
|
#define WORKPIECEHOLE_FULL_VERSION_STRING "V" WORKPIECEHOLE_VERSION_STRING "_" WORKPIECEHOLE_BUILD_STRING
|
||||||
|
|
||||||
// 构建日期
|
// 构建日期
|
||||||
|
|||||||
@ -1,5 +1,13 @@
|
|||||||
|
# 1.2.3
|
||||||
|
## build_1 2026-07-16
|
||||||
|
1. 更新算法 工件4,5歇着的情况
|
||||||
|
|
||||||
# 1.2.2
|
# 1.2.2
|
||||||
## build_1 2026-07-14
|
## build_2 2026-07-16
|
||||||
|
1. 重新调整了工件序号
|
||||||
|
2. 增加正反工件的识别
|
||||||
|
|
||||||
|
## build_1 2026-07-16
|
||||||
1. 工件3和工件5 反了。
|
1. 工件3和工件5 反了。
|
||||||
2. 每个工件有独立的工具参数调整
|
2. 每个工件有独立的工具参数调整
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@ -114,14 +114,6 @@ typedef struct
|
|||||||
int idx;
|
int idx;
|
||||||
}SSG_intPair;
|
}SSG_intPair;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int data_0;
|
|
||||||
int data_1;
|
|
||||||
double value1;
|
|
||||||
double value2;
|
|
||||||
}SSG_intPairRelationD;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -978,12 +978,17 @@ void _XOYprojection(
|
|||||||
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
|
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
|
||||||
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
|
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
|
||||||
//x轴
|
//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 x2 = a_hole.center.x + dirAngleLen * a_hole.x_dir.x;
|
||||||
double y2 = a_hole.center.y + dirAngleLen * a_hole.x_dir.y;
|
double y2 = a_hole.center.y + dirAngleLen * a_hole.x_dir.y;
|
||||||
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
|
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
|
||||||
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
|
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
|
||||||
rgb = { 255, 0, 0 }; //x轴用红色
|
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轴
|
//y轴
|
||||||
x2 = a_hole.center.x + dirAngleLen * a_hole.y_dir.x;
|
x2 = a_hole.center.x + dirAngleLen * a_hole.y_dir.x;
|
||||||
y2 = a_hole.center.y + dirAngleLen * a_hole.y_dir.y;
|
y2 = a_hole.center.y + dirAngleLen * a_hole.y_dir.y;
|
||||||
@ -1557,24 +1562,25 @@ void TuoPuFa_holePosition_test2(void)
|
|||||||
#endif
|
#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] = {
|
const char* dataPath[TPF3_TEST_GROUP] = {
|
||||||
|
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/1层/", //0
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/1层/", //0
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/2层/", //1
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/2层/", //1
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/3层/", //2
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/3层/", //2
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/4层/", //3
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/4层/", //3
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/5层/", //4
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/5层/", //4
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/6层/", //5
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/6层/", //5
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/7层/", //6
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/7层/", //6
|
||||||
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/B10歪/", //7
|
||||||
};
|
};
|
||||||
|
|
||||||
SVzNLRange fileIdx[TPF3_TEST_GROUP] = {
|
SVzNLRange fileIdx[TPF3_TEST_GROUP] = {
|
||||||
{1,11}, {1, 10}, {1,10}, {1,10}, {1, 10},
|
{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();
|
const char* ver = wd_workpieceHolePositioningVersion();
|
||||||
@ -1617,7 +1623,7 @@ void TuoPuFa_holePosition_test3(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TEST_COMPUTE_HOLE
|
#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;
|
SSG_planeCalibPara groundCalibPara;
|
||||||
//初始化成单位阵
|
//初始化成单位阵
|
||||||
@ -1701,7 +1707,7 @@ void TuoPuFa_holePosition_test3(void)
|
|||||||
|
|
||||||
sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx);
|
sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx);
|
||||||
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
|
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
|
||||||
double angleDrawLen = 15;
|
double angleDrawLen = 30;
|
||||||
double displayScale = 0.3;
|
double displayScale = 0.3;
|
||||||
cv::String imgName(calibFile);
|
cv::String imgName(calibFile);
|
||||||
_genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen);
|
_genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen);
|
||||||
@ -1710,25 +1716,26 @@ void TuoPuFa_holePosition_test3(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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] = {
|
const char* dataPath[TPF4_TEST_GROUP] = {
|
||||||
|
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/1层/", //0
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/1层/", //0
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/2层/", //1
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/2层/", //1
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/3层/", //2
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/3层/", //2
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/4层/", //3
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/4层/", //3
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/5层/", //4
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/5层/", //4
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/6层/", //5
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/6层/", //5
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/7层/", //6
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/7层/", //6
|
||||||
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/B20歪/", //7
|
||||||
};
|
};
|
||||||
|
|
||||||
SVzNLRange fileIdx[TPF4_TEST_GROUP] = {
|
SVzNLRange fileIdx[TPF4_TEST_GROUP] = {
|
||||||
{1,11}, {1, 11}, {1,11}, {1,10}, {1, 10},
|
{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();
|
const char* ver = wd_workpieceHolePositioningVersion();
|
||||||
@ -1771,7 +1778,7 @@ void TuoPuFa_holePosition_test4(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TEST_COMPUTE_HOLE
|
#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;
|
SSG_planeCalibPara groundCalibPara;
|
||||||
//初始化成单位阵
|
//初始化成单位阵
|
||||||
@ -1855,7 +1862,7 @@ void TuoPuFa_holePosition_test4(void)
|
|||||||
|
|
||||||
sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx);
|
sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx);
|
||||||
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
|
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
|
||||||
double angleDrawLen = 15;
|
double angleDrawLen = 30;
|
||||||
double displayScale = 0.3;
|
double displayScale = 0.3;
|
||||||
cv::String imgName(calibFile);
|
cv::String imgName(calibFile);
|
||||||
_genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen);
|
_genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositioning, rpy, angleDrawLen);
|
||||||
@ -1867,28 +1874,28 @@ void TuoPuFa_holePosition_test4(void)
|
|||||||
|
|
||||||
#define TPF5_TEST_GROUP 14
|
#define TPF5_TEST_GROUP 14
|
||||||
//拓普发工件孔定位(工件定位)
|
//拓普发工件孔定位(工件定位)
|
||||||
void TuoPuFa_holePosition_test5(void)
|
void TuoPuFa_holePosition_test3(void)
|
||||||
{
|
{
|
||||||
const char* dataPath[TPF5_TEST_GROUP] = {
|
const char* dataPath[TPF5_TEST_GROUP] = {
|
||||||
|
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/1层/", //0
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/1层/", //0
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/2层/", //1
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/2层/", //1
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/3层/", //2
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/3层/", //2
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/4层/", //3
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/4层/", //3
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/5层/", //4
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/5层/", //4
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/6层/", //5
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/6层/", //5
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/7层/", //6
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/7层/", //6
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/8层/", //7
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/8层/", //7
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/9层/", //8
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/9层/", //8
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/10层/", //9
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/10层/", //9
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/11层/", //10
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/11层/", //10
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/12层/", //11
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/12层/", //11
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/13层/", //12
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/13层/", //12
|
||||||
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/14层/", //13
|
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/14层/", //13
|
||||||
};
|
};
|
||||||
|
|
||||||
SVzNLRange fileIdx[TPF5_TEST_GROUP] = {
|
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,11}, {1, 10}, {1,11}, {1,10}, {1,10},
|
||||||
{1, 10}, {1,10}, {1,11}, {1,10}
|
{1, 10}, {1,10}, {1,11}, {1,10}
|
||||||
};
|
};
|
||||||
@ -2742,9 +2749,9 @@ int main()
|
|||||||
{
|
{
|
||||||
//TuoPuFa_holePosition_test();
|
//TuoPuFa_holePosition_test();
|
||||||
//TuoPuFa_holePosition_test2();
|
//TuoPuFa_holePosition_test2();
|
||||||
TuoPuFa_holePosition_test3();
|
//TuoPuFa_holePosition_test3();
|
||||||
TuoPuFa_holePosition_test4();
|
TuoPuFa_holePosition_test4();
|
||||||
//TuoPuFa_holePosition_test5();
|
TuoPuFa_holePosition_test5();
|
||||||
}
|
}
|
||||||
else if (keSG_华航孔定位 == testMode)
|
else if (keSG_华航孔定位 == testMode)
|
||||||
HuaHang_holePosition_test();
|
HuaHang_holePosition_test();
|
||||||
|
|||||||
@ -29,10 +29,12 @@ namespace ConfigXmlUtils
|
|||||||
* @param root XML 根节点
|
* @param root XML 根节点
|
||||||
* @param list 输出的矩阵列表
|
* @param list 输出的矩阵列表
|
||||||
* @param defaultEulerOrder 当 XML 中无 eulerOrder 属性时使用的默认值
|
* @param defaultEulerOrder 当 XML 中无 eulerOrder 属性时使用的默认值
|
||||||
|
* @param defaultCalibType 当 XML 中无 calibType 属性时使用的默认值(0=眼在手外,1=眼在手上)
|
||||||
*/
|
*/
|
||||||
void LoadHandEyeCalibMatrixs(tinyxml2::XMLElement* root,
|
void LoadHandEyeCalibMatrixs(tinyxml2::XMLElement* root,
|
||||||
std::vector<VrHandEyeCalibMatrix>& list,
|
std::vector<VrHandEyeCalibMatrix>& list,
|
||||||
int defaultEulerOrder = 11);
|
int defaultEulerOrder = 11,
|
||||||
|
int defaultCalibType = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 保存手眼标定矩阵列表到 XML 根节点(<HandEyeCalibMatrixs> 格式)
|
* @brief 保存手眼标定矩阵列表到 XML 根节点(<HandEyeCalibMatrixs> 格式)
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
struct VrHandEyeCalibMatrix
|
struct VrHandEyeCalibMatrix
|
||||||
{
|
{
|
||||||
int cameraIndex;
|
int cameraIndex;
|
||||||
|
int calibType; // 0=眼在手外,1=眼在手上
|
||||||
double matrix[16];
|
double matrix[16];
|
||||||
int eulerOrder;
|
int eulerOrder;
|
||||||
double rotX;
|
double rotX;
|
||||||
@ -35,6 +36,7 @@ struct VrHandEyeCalibMatrix
|
|||||||
|
|
||||||
VrHandEyeCalibMatrix()
|
VrHandEyeCalibMatrix()
|
||||||
: cameraIndex(1)
|
: cameraIndex(1)
|
||||||
|
, calibType(0)
|
||||||
, eulerOrder(11)
|
, eulerOrder(11)
|
||||||
, rotX(0.0)
|
, rotX(0.0)
|
||||||
, rotY(0.0)
|
, rotY(0.0)
|
||||||
|
|||||||
@ -12,11 +12,22 @@ namespace ConfigXmlUtils
|
|||||||
|
|
||||||
static void LoadSingleHandEyeCalibMatrix(XMLElement* handEyeElement,
|
static void LoadSingleHandEyeCalibMatrix(XMLElement* handEyeElement,
|
||||||
VrHandEyeCalibMatrix& calibMatrix,
|
VrHandEyeCalibMatrix& calibMatrix,
|
||||||
int defaultEulerOrder)
|
int defaultEulerOrder,
|
||||||
|
int defaultCalibType)
|
||||||
{
|
{
|
||||||
if (handEyeElement->Attribute("cameraIndex"))
|
if (handEyeElement->Attribute("cameraIndex"))
|
||||||
calibMatrix.cameraIndex = handEyeElement->IntAttribute("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++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
char attrName[32];
|
char attrName[32];
|
||||||
@ -60,7 +71,8 @@ static void LoadSingleHandEyeCalibMatrix(XMLElement* handEyeElement,
|
|||||||
|
|
||||||
void LoadHandEyeCalibMatrixs(XMLElement* root,
|
void LoadHandEyeCalibMatrixs(XMLElement* root,
|
||||||
std::vector<VrHandEyeCalibMatrix>& list,
|
std::vector<VrHandEyeCalibMatrix>& list,
|
||||||
int defaultEulerOrder)
|
int defaultEulerOrder,
|
||||||
|
int defaultCalibType)
|
||||||
{
|
{
|
||||||
// 优先找 <HandEyeCalibMatrixs>
|
// 优先找 <HandEyeCalibMatrixs>
|
||||||
XMLElement* containerElement = root->FirstChildElement("HandEyeCalibMatrixs");
|
XMLElement* containerElement = root->FirstChildElement("HandEyeCalibMatrixs");
|
||||||
@ -76,7 +88,8 @@ void LoadHandEyeCalibMatrixs(XMLElement* root,
|
|||||||
{
|
{
|
||||||
VrHandEyeCalibMatrix calibMatrix;
|
VrHandEyeCalibMatrix calibMatrix;
|
||||||
calibMatrix.cameraIndex = static_cast<int>(list.size()) + 1; // 默认递增
|
calibMatrix.cameraIndex = static_cast<int>(list.size()) + 1; // 默认递增
|
||||||
LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, defaultEulerOrder);
|
LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix,
|
||||||
|
defaultEulerOrder, defaultCalibType);
|
||||||
list.push_back(calibMatrix);
|
list.push_back(calibMatrix);
|
||||||
handEyeElement = handEyeElement->NextSiblingElement("HandEyeCalibMatrix");
|
handEyeElement = handEyeElement->NextSiblingElement("HandEyeCalibMatrix");
|
||||||
}
|
}
|
||||||
@ -89,7 +102,8 @@ void LoadHandEyeCalibMatrixs(XMLElement* root,
|
|||||||
{
|
{
|
||||||
VrHandEyeCalibMatrix calibMatrix;
|
VrHandEyeCalibMatrix calibMatrix;
|
||||||
calibMatrix.cameraIndex = 1;
|
calibMatrix.cameraIndex = 1;
|
||||||
LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix, defaultEulerOrder);
|
LoadSingleHandEyeCalibMatrix(handEyeElement, calibMatrix,
|
||||||
|
defaultEulerOrder, defaultCalibType);
|
||||||
list.push_back(calibMatrix);
|
list.push_back(calibMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,6 +118,7 @@ void SaveHandEyeCalibMatrixs(XMLDocument& doc,
|
|||||||
{
|
{
|
||||||
XMLElement* handEyeElement = doc.NewElement("HandEyeCalibMatrix");
|
XMLElement* handEyeElement = doc.NewElement("HandEyeCalibMatrix");
|
||||||
handEyeElement->SetAttribute("cameraIndex", calibMatrix.cameraIndex);
|
handEyeElement->SetAttribute("cameraIndex", calibMatrix.cameraIndex);
|
||||||
|
handEyeElement->SetAttribute("calibType", calibMatrix.calibType);
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
char attrName[32];
|
char attrName[32];
|
||||||
|
|||||||
@ -57,6 +57,26 @@ padding: 2px;</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayoutCalibType">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelCalibType">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>120</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>标定方式:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboCalibType"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="labelStatus">
|
<widget class="QLabel" name="labelStatus">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|||||||
@ -30,6 +30,7 @@ struct HandEyeCalibCameraInfo
|
|||||||
struct HandEyeCalibData
|
struct HandEyeCalibData
|
||||||
{
|
{
|
||||||
int cameraIndex = 0;
|
int cameraIndex = 0;
|
||||||
|
int calibType = 0; // 0=眼在手外,1=眼在手上
|
||||||
double matrix[16] = {
|
double matrix[16] = {
|
||||||
1.0, 0.0, 0.0, 0.0,
|
1.0, 0.0, 0.0, 0.0,
|
||||||
0.0, 1.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);
|
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 设置指定相机的欧拉角顺序与补偿旋转
|
* @brief 设置指定相机的欧拉角顺序与补偿旋转
|
||||||
*/
|
*/
|
||||||
@ -165,6 +183,7 @@ signals:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onCameraSelectionChanged(int index);
|
void onCameraSelectionChanged(int index);
|
||||||
|
void onCalibTypeChanged(int index);
|
||||||
void onLoadCalibMatrixClicked();
|
void onLoadCalibMatrixClicked();
|
||||||
void onSaveCalibMatrixClicked();
|
void onSaveCalibMatrixClicked();
|
||||||
|
|
||||||
@ -174,6 +193,7 @@ private:
|
|||||||
void clearMatrix();
|
void clearMatrix();
|
||||||
void displayIdentityMatrix();
|
void displayIdentityMatrix();
|
||||||
void updateCalibStatus(bool isCalibrated);
|
void updateCalibStatus(bool isCalibrated);
|
||||||
|
void updateCalibType(int calibType);
|
||||||
|
|
||||||
// 从矩阵编辑框读取当前矩阵值
|
// 从矩阵编辑框读取当前矩阵值
|
||||||
bool readMatrixFromUI(double outMatrix[16]) const;
|
bool readMatrixFromUI(double outMatrix[16]) const;
|
||||||
@ -187,6 +207,7 @@ private:
|
|||||||
Ui::HandEyeCalibWidget* ui = nullptr;
|
Ui::HandEyeCalibWidget* ui = nullptr;
|
||||||
|
|
||||||
QComboBox* m_comboCamera;
|
QComboBox* m_comboCamera;
|
||||||
|
QComboBox* m_comboCalibType;
|
||||||
QLabel* m_labelStatus;
|
QLabel* m_labelStatus;
|
||||||
QLineEdit* m_matrixEdits[4][4]; // 4x4 矩阵编辑框
|
QLineEdit* m_matrixEdits[4][4]; // 4x4 矩阵编辑框
|
||||||
QPushButton* m_btnLoad;
|
QPushButton* m_btnLoad;
|
||||||
@ -195,6 +216,7 @@ private:
|
|||||||
QVector<HandEyeCalibData> m_calibDataCache; // 按相机索引缓存
|
QVector<HandEyeCalibData> m_calibDataCache; // 按相机索引缓存
|
||||||
QString m_defaultFilePath;
|
QString m_defaultFilePath;
|
||||||
bool m_matrixEditable;
|
bool m_matrixEditable;
|
||||||
|
int m_defaultCalibType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HANDEYECALIBWIDGET_H
|
#endif // HANDEYECALIBWIDGET_H
|
||||||
|
|||||||
@ -12,10 +12,12 @@ HandEyeCalibWidget::HandEyeCalibWidget(QWidget *parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, ui(new Ui::HandEyeCalibWidget)
|
, ui(new Ui::HandEyeCalibWidget)
|
||||||
, m_comboCamera(nullptr)
|
, m_comboCamera(nullptr)
|
||||||
|
, m_comboCalibType(nullptr)
|
||||||
, m_labelStatus(nullptr)
|
, m_labelStatus(nullptr)
|
||||||
, m_btnLoad(nullptr)
|
, m_btnLoad(nullptr)
|
||||||
, m_btnSave(nullptr)
|
, m_btnSave(nullptr)
|
||||||
, m_matrixEditable(false)
|
, m_matrixEditable(false)
|
||||||
|
, m_defaultCalibType(0)
|
||||||
{
|
{
|
||||||
memset(m_matrixEdits, 0, sizeof(m_matrixEdits));
|
memset(m_matrixEdits, 0, sizeof(m_matrixEdits));
|
||||||
setupUI();
|
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,
|
void HandEyeCalibWidget::setExtrinsicData(int cameraIndex, int eulerOrder,
|
||||||
double rotX, double rotY, double rotZ)
|
double rotX, double rotY, double rotZ)
|
||||||
{
|
{
|
||||||
@ -214,13 +248,16 @@ void HandEyeCalibWidget::onCameraSelectionChanged(int index)
|
|||||||
if (index < 0 || !m_comboCamera || m_comboCamera->count() == 0) {
|
if (index < 0 || !m_comboCamera || m_comboCamera->count() == 0) {
|
||||||
m_btnLoad->setEnabled(false);
|
m_btnLoad->setEnabled(false);
|
||||||
m_btnSave->setEnabled(false);
|
m_btnSave->setEnabled(false);
|
||||||
|
m_comboCalibType->setEnabled(false);
|
||||||
displayIdentityMatrix();
|
displayIdentityMatrix();
|
||||||
updateCalibStatus(false);
|
updateCalibStatus(false);
|
||||||
|
updateCalibType(m_defaultCalibType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_btnLoad->setEnabled(true);
|
m_btnLoad->setEnabled(true);
|
||||||
m_btnSave->setEnabled(true);
|
m_btnSave->setEnabled(true);
|
||||||
|
m_comboCalibType->setEnabled(true);
|
||||||
|
|
||||||
int camIdx = m_comboCamera->itemData(index).toInt();
|
int camIdx = m_comboCamera->itemData(index).toInt();
|
||||||
const HandEyeCalibData* data = findCalibData(camIdx);
|
const HandEyeCalibData* data = findCalibData(camIdx);
|
||||||
@ -231,7 +268,22 @@ void HandEyeCalibWidget::onCameraSelectionChanged(int index)
|
|||||||
displayIdentityMatrix();
|
displayIdentityMatrix();
|
||||||
updateCalibStatus(false);
|
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()
|
void HandEyeCalibWidget::onLoadCalibMatrixClicked()
|
||||||
@ -254,6 +306,11 @@ void HandEyeCalibWidget::onLoadCalibMatrixClicked()
|
|||||||
settings.setIniCodec("UTF-8");
|
settings.setIniCodec("UTF-8");
|
||||||
settings.beginGroup("CalibMatrixInfo_0");
|
settings.beginGroup("CalibMatrixInfo_0");
|
||||||
|
|
||||||
|
int calibType = settings.value("eCalibType", m_defaultCalibType).toInt();
|
||||||
|
if (calibType != 0 && calibType != 1) {
|
||||||
|
calibType = m_defaultCalibType;
|
||||||
|
}
|
||||||
|
|
||||||
double matrix[16];
|
double matrix[16];
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
int row = i / 4;
|
int row = i / 4;
|
||||||
@ -264,6 +321,7 @@ void HandEyeCalibWidget::onLoadCalibMatrixClicked()
|
|||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
setCalibData(camIdx, matrix, true);
|
setCalibData(camIdx, matrix, true);
|
||||||
|
setCalibType(camIdx, calibType);
|
||||||
emit calibMatrixLoaded(camIdx, matrix);
|
emit calibMatrixLoaded(camIdx, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,10 +380,15 @@ void HandEyeCalibWidget::setupUI()
|
|||||||
matrixFont.setPointSize(16);
|
matrixFont.setPointSize(16);
|
||||||
|
|
||||||
m_comboCamera = ui->comboCamera;
|
m_comboCamera = ui->comboCamera;
|
||||||
|
m_comboCalibType = ui->comboCalibType;
|
||||||
m_labelStatus = ui->labelStatus;
|
m_labelStatus = ui->labelStatus;
|
||||||
m_btnLoad = ui->btnLoad;
|
m_btnLoad = ui->btnLoad;
|
||||||
m_btnSave = ui->btnSave;
|
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][0] = ui->editMatrix00;
|
||||||
m_matrixEdits[0][1] = ui->editMatrix01;
|
m_matrixEdits[0][1] = ui->editMatrix01;
|
||||||
m_matrixEdits[0][2] = ui->editMatrix02;
|
m_matrixEdits[0][2] = ui->editMatrix02;
|
||||||
@ -363,6 +426,8 @@ void HandEyeCalibWidget::setupUI()
|
|||||||
|
|
||||||
connect(m_comboCamera, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
connect(m_comboCamera, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
this, &HandEyeCalibWidget::onCameraSelectionChanged);
|
this, &HandEyeCalibWidget::onCameraSelectionChanged);
|
||||||
|
connect(m_comboCalibType, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
|
this, &HandEyeCalibWidget::onCalibTypeChanged);
|
||||||
connect(m_btnLoad, &QPushButton::clicked,
|
connect(m_btnLoad, &QPushButton::clicked,
|
||||||
this, &HandEyeCalibWidget::onLoadCalibMatrixClicked);
|
this, &HandEyeCalibWidget::onLoadCalibMatrixClicked);
|
||||||
connect(m_btnSave, &QPushButton::clicked,
|
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
|
bool HandEyeCalibWidget::readMatrixFromUI(double outMatrix[16]) const
|
||||||
{
|
{
|
||||||
for (int r = 0; r < 4; ++r) {
|
for (int r = 0; r < 4; ++r) {
|
||||||
@ -455,6 +532,7 @@ HandEyeCalibData& HandEyeCalibWidget::ensureCalibData(int cameraIndex)
|
|||||||
|
|
||||||
HandEyeCalibData newData;
|
HandEyeCalibData newData;
|
||||||
newData.cameraIndex = cameraIndex;
|
newData.cameraIndex = cameraIndex;
|
||||||
|
newData.calibType = m_defaultCalibType;
|
||||||
m_calibDataCache.append(newData);
|
m_calibDataCache.append(newData);
|
||||||
return m_calibDataCache.last();
|
return m_calibDataCache.last();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user