工件孔更新算法,斜着角度不对的问题
This commit is contained in:
parent
9926c9907e
commit
b15533e36e
@ -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
|
||||
|
||||
// 构建日期
|
||||
|
||||
@ -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. 每个工件有独立的工具参数调整
|
||||
|
||||
|
||||
Binary file not shown.
@ -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;
|
||||
|
||||
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 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();
|
||||
|
||||
@ -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<VrHandEyeCalibMatrix>& list,
|
||||
int defaultEulerOrder = 11);
|
||||
int defaultEulerOrder = 11,
|
||||
int defaultCalibType = 0);
|
||||
|
||||
/**
|
||||
* @brief 保存手眼标定矩阵列表到 XML 根节点(<HandEyeCalibMatrixs> 格式)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<VrHandEyeCalibMatrix>& list,
|
||||
int defaultEulerOrder)
|
||||
int defaultEulerOrder,
|
||||
int defaultCalibType)
|
||||
{
|
||||
// 优先找 <HandEyeCalibMatrixs>
|
||||
XMLElement* containerElement = root->FirstChildElement("HandEyeCalibMatrixs");
|
||||
@ -76,7 +88,8 @@ void LoadHandEyeCalibMatrixs(XMLElement* root,
|
||||
{
|
||||
VrHandEyeCalibMatrix calibMatrix;
|
||||
calibMatrix.cameraIndex = static_cast<int>(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];
|
||||
|
||||
@ -57,6 +57,26 @@ padding: 2px;</string>
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
<widget class="QLabel" name="labelStatus">
|
||||
<property name="text">
|
||||
|
||||
@ -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<HandEyeCalibData> m_calibDataCache; // 按相机索引缓存
|
||||
QString m_defaultFilePath;
|
||||
bool m_matrixEditable;
|
||||
int m_defaultCalibType;
|
||||
};
|
||||
|
||||
#endif // HANDEYECALIBWIDGET_H
|
||||
|
||||
@ -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<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &HandEyeCalibWidget::onCameraSelectionChanged);
|
||||
connect(m_comboCalibType, static_cast<void(QComboBox::*)(int)>(&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();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user