diff --git a/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/DetectPresenter.cpp b/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/DetectPresenter.cpp index 28f41b7..ae12c80 100644 --- a/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/DetectPresenter.cpp +++ b/App/RodAndBarPosition/RodAndBarPositionApp/Presenter/Src/DetectPresenter.cpp @@ -28,18 +28,6 @@ HECEulerOrder ToHandEyeEulerOrder(int eulerOrder) } } -HECCalibResult ToHandEyeCalibResult(const double clibMatrix[16]) -{ - HECCalibResult calibResult; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - calibResult.R.at(i, j) = clibMatrix[i * 4 + j]; - } - calibResult.T.at(i) = clibMatrix[i * 4 + 3]; - } - return calibResult; -} - } // namespace DetectPresenter::DetectPresenter(/* args */) @@ -145,7 +133,7 @@ int DetectPresenter::DetectRod( return ERR_CODE(DEV_NOT_FIND); } - const HECCalibResult calibResult = ToHandEyeCalibResult(clibMatrix); + const HECCalibResult calibResult = HECCalibResult::fromHomogeneousArray(clibMatrix); const HECEulerOrder hecEulerOrder = ToHandEyeEulerOrder(eulerOrder); // 构建检测结果:生成点云图像 diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h index 521008b..7b3767f 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h @@ -13,7 +13,6 @@ #include "IYWorkpieceHoleStatus.h" #include "PointCloudImageUtils.h" #include "VrDateUtils.h" -#include "CoordinateTransform.h" class DetectPresenter { diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/WorkpieceHolePresenter.h b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/WorkpieceHolePresenter.h index ecfbc9e..9613c40 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/WorkpieceHolePresenter.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/WorkpieceHolePresenter.h @@ -68,40 +68,6 @@ public: // 手眼标定矩阵管理 CalibMatrix GetClibMatrix(int index) const; - // ============ 坐标转换接口 ============ - - /** - * @brief 将算法检测结果(相机坐标系)转换为机器人坐标系 - * - * @param workpieceInfo 算法输出的工件信息(相机坐标系) - * @param robotPose 机器人当前位姿 - * @param handEye 六轴手眼标定矩阵 - * @param targetPose 输出的目标抓取位姿(机器人坐标系) - * - * 使用说明: - * - Eye-in-Hand 模式:相机固定在机器人末端 - * - 算法输出的 x_dir, y_dir, z_dir 为方向向量 - * - 输出的 targetPose 为机器人基坐标系下的位姿 - */ - void ConvertWorkpieceToRobotPose(const WD_workpieceInfo& workpieceInfo, - const CTRobotPose& robotPose, - const CTSixAxisCalibResult& handEye, - CTRobotPose& targetPose); - - /** - * @brief 将算法检测结果转换为机器人坐标系(Eye-to-Hand模式) - * - * @param workpieceInfo 算法输出的工件信息(相机坐标系) - * @param cameraToBase 相机到机器人基座的标定矩阵 - * @param targetPose 输出的目标抓取位姿(机器人坐标系) - * - * 使用说明: - * - Eye-to-Hand 模式:相机固定在外部 - */ - void ConvertWorkpieceToRobotPoseEyeToHand(const WD_workpieceInfo& workpieceInfo, - const CTSixAxisCalibResult& cameraToBase, - CTRobotPose& targetPose); - // 实现IVrConfigChangeNotify接口 virtual void OnConfigChanged(const ConfigResult& configResult) override; diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp index c941b1f..5d19d58 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp @@ -2,13 +2,9 @@ #include "workpieceHolePositioning_Export.h" #include "SG_baseAlgo_Export.h" #include "AlgoParamConverter.h" +#include "IHandEyeCalib.h" #include -#include -#include -#include -#include -#include "CoordinateTransform.h" -#include "VrConvert.h" +#include DetectPresenter::DetectPresenter(/* args */) { @@ -91,15 +87,15 @@ int DetectPresenter::DetectWorkpieceHole( AlgoParamConverter::LogAlgoParams("[Algo Thread]", workpiecePara, lineSegPara, filterParam, growParam, groundCalibPara, clibMatrix); } - +#if 0 // 数据预处理:调平和去除地面(使用当前相机的调平参数) if(cameraCalibParam){ - LOG_DEBUG("Processing data with plane calibration\n"); - double groundH = -1; + LOG_DEBUG("Processing data with plane calibration\n"); for(size_t i = 0; i < xyzData.size(); i++){ - wd_lineDataR(xyzData[i], cameraCalibParam->planeCalib, groundH); + wd_lineDataR(xyzData[i], cameraCalibParam->planeCalib, -1); } } +#endif int errCode = 0; CVrTimeUtils oTimeUtils; @@ -124,19 +120,16 @@ int DetectPresenter::DetectWorkpieceHole( LOG_INFO("wd_workpieceHolePositioning: found %zu workpieces, err=%d runtime=%.3fms\n", workpiecePositioning.size(), errCode, oTimeUtils.GetElapsedTimeInMilliSec()); ERR_CODE_RETURN(errCode); - // 从4x4齐次变换矩阵中提取旋转矩阵R(3x3)和平移向量T(3x1) - // clibMatrix 是行优先存储的4x4矩阵 - cv::Mat R = cv::Mat::zeros(3, 3, CV_64F); - cv::Mat T = cv::Mat::zeros(3, 1, CV_64F); - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - R.at(i, j) = clibMatrix[i * 4 + j]; - } - T.at(i, 0) = clibMatrix[i * 4 + 3]; + // 创建手眼标定实例 + std::unique_ptr handEyeCalib( + CreateHandEyeCalibInstance(), + DestroyHandEyeCalibInstance); + if (!handEyeCalib) { + LOG_ERROR("Failed to create HandEyeCalib instance\n"); + return ERR_CODE(DEV_NOT_FIND); } - // 构建用于可视化的点数组 - std::vector> objOps; + const HECCalibResult calibResult = HECCalibResult::fromHomogeneousArray(clibMatrix); // 处理每个工件的检测结果 for (size_t i = 0; i < workpiecePositioning.size(); i++) { @@ -148,52 +141,44 @@ int DetectPresenter::DetectWorkpieceHole( } // 六轴转换:位置+姿态(转换到机械臂坐标系) - SVzNL3DPoint centerEye = workpiece.center; + HECPoint3D eyeCenter(workpiece.center.x, workpiece.center.y, workpiece.center.z); - // 1. 位置转换:使用 pointRT_2 进行坐标变换 - cv::Point3d ptEye(centerEye.x, centerEye.y, centerEye.z); - cv::Point3d ptRobot; - pointRT_2(R, T, ptEye, ptRobot); - - // 2. 姿态转换:按照测试代码的方式处理方向向量 - // 从算法输出获取方向向量 - std::vector dirVectors_eye(3); - dirVectors_eye[0] = cv::Point3d(workpiece.x_dir.x, workpiece.x_dir.y, workpiece.x_dir.z); - dirVectors_eye[1] = cv::Point3d(workpiece.y_dir.x, workpiece.y_dir.y, workpiece.y_dir.z); - dirVectors_eye[2] = cv::Point3d(workpiece.z_dir.x, workpiece.z_dir.y, workpiece.z_dir.z); + // 构建方向向量(眼坐标系) + std::vector dirVectors_eye(3); + dirVectors_eye[0] = HECPoint3D(workpiece.x_dir.x, workpiece.x_dir.y, workpiece.x_dir.z); + dirVectors_eye[1] = HECPoint3D(workpiece.y_dir.x, workpiece.y_dir.y, workpiece.y_dir.z); + dirVectors_eye[2] = HECPoint3D(workpiece.z_dir.x, workpiece.z_dir.y, workpiece.z_dir.z); // 根据配置决定方向向量反向 switch (dirVectorInvert) { case DIR_INVERT_NONE: - // 不反向 break; case DIR_INVERT_XY: - // X和Y方向反向 - dirVectors_eye[0] = cv::Point3d(-dirVectors_eye[0].x, -dirVectors_eye[0].y, -dirVectors_eye[0].z); - dirVectors_eye[1] = cv::Point3d(-dirVectors_eye[1].x, -dirVectors_eye[1].y, -dirVectors_eye[1].z); + dirVectors_eye[0] = dirVectors_eye[0] * (-1.0); + dirVectors_eye[1] = dirVectors_eye[1] * (-1.0); break; case DIR_INVERT_XZ: - // X和Z方向反向 - dirVectors_eye[0] = cv::Point3d(-dirVectors_eye[0].x, -dirVectors_eye[0].y, -dirVectors_eye[0].z); - dirVectors_eye[2] = cv::Point3d(-dirVectors_eye[2].x, -dirVectors_eye[2].y, -dirVectors_eye[2].z); + dirVectors_eye[0] = dirVectors_eye[0] * (-1.0); + dirVectors_eye[2] = dirVectors_eye[2] * (-1.0); break; case DIR_INVERT_YZ: default: - // Y和Z方向反向(默认,兼容原有行为) - dirVectors_eye[1] = cv::Point3d(-dirVectors_eye[1].x, -dirVectors_eye[1].y, -dirVectors_eye[1].z); - dirVectors_eye[2] = cv::Point3d(-dirVectors_eye[2].x, -dirVectors_eye[2].y, -dirVectors_eye[2].z); + dirVectors_eye[1] = dirVectors_eye[1] * (-1.0); + dirVectors_eye[2] = dirVectors_eye[2] * (-1.0); break; } - // 使用 pointRotate 对方向向量进行旋转变换 - std::vector dirVectors_robot; + // 1. 位置转换:R * P_eye + T + HECPoint3D ptRobot; + handEyeCalib->TransformPoint(calibResult.R, calibResult.T, eyeCenter, ptRobot); + + // 2. 方向向量旋转变换(仅旋转,不平移) + std::vector dirVectors_robot(3); for (int j = 0; j < 3; j++) { - cv::Point3d rt_pt; - pointRotate(R, dirVectors_eye[j], rt_pt); - dirVectors_robot.push_back(rt_pt); + handEyeCalib->RotatePoint(calibResult.R, dirVectors_eye[j], dirVectors_robot[j]); } - // 3. 构建旋转矩阵(按照测试代码的方式) + // 3. 构建旋转矩阵(列向量形式) double R_pose[3][3]; R_pose[0][0] = dirVectors_robot[0].x; R_pose[0][1] = dirVectors_robot[1].x; @@ -205,7 +190,7 @@ int DetectPresenter::DetectWorkpieceHole( R_pose[2][1] = dirVectors_robot[1].z; R_pose[2][2] = dirVectors_robot[2].z; - // 4. 使用 rotationMatrixToEulerZYX 转换为欧拉角(外旋ZYX,即RZ-RY-RX) + // 4. 使用算法库的 rotationMatrixToEulerZYX 转换为欧拉角(返回角度) SSG_EulerAngles robotRpy = rotationMatrixToEulerZYX(R_pose); // 将机器人坐标系下的位姿添加到positions列表 @@ -213,21 +198,12 @@ int DetectPresenter::DetectWorkpieceHole( centerRobotPos.x = ptRobot.x; centerRobotPos.y = ptRobot.y; centerRobotPos.z = ptRobot.z; - centerRobotPos.roll = robotRpy.roll; // 已经是角度 - centerRobotPos.pitch = robotRpy.pitch; // 已经是角度 - centerRobotPos.yaw = robotRpy.yaw; // 已经是角度 + centerRobotPos.roll = robotRpy.roll; + centerRobotPos.pitch = robotRpy.pitch; + centerRobotPos.yaw = robotRpy.yaw; detectionResult.positions.push_back(centerRobotPos); - // 添加中心点到可视化列表 - std::vector holePoints; - for(size_t j = 0; j < workpiece.holes.size(); j++){ - SVzNL3DPoint holeEye = workpiece.holes[j]; - holePoints.push_back(holeEye); - } - holePoints.push_back(centerEye); - objOps.push_back(holePoints); - if(debugParam.enableDebug && debugParam.printDetailLog){ LOG_INFO("[Algo Thread] Direction vectors (eye): X=(%.3f,%.3f,%.3f), Y=(%.3f,%.3f,%.3f), Z=(%.3f,%.3f,%.3f)\n", workpiece.x_dir.x, workpiece.x_dir.y, workpiece.x_dir.z, @@ -237,111 +213,29 @@ int DetectPresenter::DetectWorkpieceHole( dirVectors_robot[0].x, dirVectors_robot[0].y, dirVectors_robot[0].z, dirVectors_robot[1].x, dirVectors_robot[1].y, dirVectors_robot[1].z, dirVectors_robot[2].x, dirVectors_robot[2].y, dirVectors_robot[2].z); - LOG_INFO("[Algo Thread] Center Eye Coords: X=%.2f, Y=%.2f, Z=%.2f\n", - centerEye.x, centerEye.y, centerEye.z); - LOG_INFO("[Algo Thread] Center Robot Coords: X=%.2f, Y=%.2f, Z=%.2f, R=%.4f, P=%.4f, Y=%.4f\n", + LOG_INFO("[Algo Thread] Center Eye Coords: X=%.3f, Y=%.3f, Z=%.3f\n", + workpiece.center.x, workpiece.center.y, workpiece.center.z); + LOG_INFO("[Algo Thread] Center Robot Coords: X=%.3f, Y=%.3f, Z=%.3f, R=%.4f, P=%.4f, Y=%.4f\n", ptRobot.x, ptRobot.y, ptRobot.z, centerRobotPos.roll, centerRobotPos.pitch, centerRobotPos.yaw); } } - // 从点云数据生成投影图像(单色灰色点云 + 红色孔位标记) + // 使用 PointCloudCanvas 生成点云图像(灰色底图 + 红色孔位标记 + 中心点编号) { - // 固定图像尺寸 - int imgRows = 992; - int imgCols = 1056; - int x_skip = 50; - int y_skip = 50; - - // 计算点云范围 - double xMin = 1e10, xMax = -1e10, yMin = 1e10, yMax = -1e10; - for (const auto& line : xyzData) { - for (const auto& pt : line) { - if (pt.pt3D.z < 1e-4) continue; - xMin = std::min(xMin, (double)pt.pt3D.x); - xMax = std::max(xMax, (double)pt.pt3D.x); - yMin = std::min(yMin, (double)pt.pt3D.y); - yMax = std::max(yMax, (double)pt.pt3D.y); + PointCloudCanvas canvas = PointCloudCanvas::Create(xyzData); + for (size_t i = 0; i < workpiecePositioning.size(); i++) { + const WD_workpieceInfo& workpiece = workpiecePositioning[i]; + // 红色小圆点标记每个孔 + for (size_t j = 0; j < workpiece.holes.size(); j++) { + canvas.drawPoint(workpiece.holes[j].x, workpiece.holes[j].y, QColor(255, 0, 0), 4); } + // 中心点标记 + 白色编号 + canvas.drawPoint(workpiece.center.x, workpiece.center.y, QColor(255, 0, 0), 4); + canvas.drawText(workpiece.center.x, workpiece.center.y, + QString("%1").arg(i + 1), Qt::white, 14); } - - // 不扩展边界,直接使用点云范围 - - // 计算投影比例 - double y_rows = (double)(imgRows - y_skip * 2); - double x_cols = (double)(imgCols - x_skip * 2); - double x_scale = (xMax - xMin) / x_cols; - double y_scale = (yMax - yMin) / y_rows; - if (x_scale < y_scale) - x_scale = y_scale; - else - y_scale = x_scale; - - // 创建图像 - QImage image(imgCols, imgRows, QImage::Format_RGB888); - image.fill(Qt::black); - QPainter painter(&image); - painter.setRenderHint(QPainter::Antialiasing); - - // 绘制点云数据 - 使用单色灰色 - QColor grayColor(150, 150, 150); - for (const auto& scanLine : xyzData) { - for (const auto& point : scanLine) { - if (point.pt3D.z < 1e-4) continue; - - int px = (int)((point.pt3D.x - xMin) / x_scale + x_skip); - int py = (int)((point.pt3D.y - yMin) / y_scale + y_skip); - - if (px >= 0 && px < imgCols && py >= 0 && py < imgRows) { - painter.setPen(QPen(grayColor, 1)); - painter.drawPoint(px, py); - } - } - } - - // 绘制孔位标记 - 使用红色 - if (!objOps.empty()) { - QColor holeColor(255, 0, 0); // 红色 - painter.setPen(QPen(holeColor, 1)); - painter.setBrush(QBrush(holeColor)); - - for (size_t i = 0; i < objOps.size(); i++) { - const auto& holeGroup = objOps[i]; - size_t groupSize = holeGroup.size(); - - for (size_t j = 0; j < groupSize; j++) { - const SVzNL3DPoint& hole = holeGroup[j]; - - // 跳过全0的点 - if (fabs(hole.x) < 0.0001 && fabs(hole.y) < 0.0001 && fabs(hole.z) < 0.0001) { - continue; - } - - int px = (int)((hole.x - xMin) / x_scale + x_skip); - int py = (int)((hole.y - yMin) / y_scale + y_skip); - - if (px >= 0 && px < imgCols && py >= 0 && py < imgRows) { - // 绘制圆点标记 - int circleSize = 2; - painter.drawEllipse(px - circleSize/2, py - circleSize/2, circleSize, circleSize); - - // 只有中心点(最后一个点)才绘制编号 - if (j == groupSize - 1) { - painter.setPen(QPen(Qt::white, 1)); - QFont font("Arial", 14, QFont::Bold); - painter.setFont(font); - painter.drawText(px + 8, py + 6, QString("%1").arg(i + 1)); - - // 恢复画笔 - painter.setPen(QPen(holeColor, 1)); - painter.setBrush(QBrush(holeColor)); - } - } - } - } - } - - detectionResult.image = image; + detectionResult.image = canvas.image(); } if(debugParam.enableDebug && debugParam.saveDebugImage){ diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp index c0248af..17c3ac5 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp @@ -255,88 +255,6 @@ CalibMatrix WorkpieceHolePresenter::GetClibMatrix(int index) const return clibMatrix; } -// ============ 坐标转换实现 ============ - -void WorkpieceHolePresenter::ConvertWorkpieceToRobotPose(const WD_workpieceInfo& workpieceInfo, - const CTRobotPose& robotPose, - const CTSixAxisCalibResult& handEye, - CTRobotPose& targetPose) -{ - // 1. 从方向向量构建旋转矩阵 - CTRotationMatrix rotMatrix; - rotMatrix.at(0, 0) = workpieceInfo.x_dir.x; - rotMatrix.at(1, 0) = workpieceInfo.x_dir.y; - rotMatrix.at(2, 0) = workpieceInfo.x_dir.z; - rotMatrix.at(0, 1) = workpieceInfo.y_dir.x; - rotMatrix.at(1, 1) = workpieceInfo.y_dir.y; - rotMatrix.at(2, 1) = workpieceInfo.y_dir.z; - rotMatrix.at(0, 2) = workpieceInfo.z_dir.x; - rotMatrix.at(1, 2) = workpieceInfo.z_dir.y; - rotMatrix.at(2, 2) = workpieceInfo.z_dir.z; - - // 2. 将旋转矩阵转换为欧拉角 - CTEulerAngles eulerAngles = CCoordinateTransform::rotationMatrixToEuler(rotMatrix, CTEulerOrder::sZYX); - - // 3. 构造相机坐标系下的目标位姿 - CTCameraPose cameraPose( - workpieceInfo.center.x, - workpieceInfo.center.y, - workpieceInfo.center.z, - eulerAngles.roll, - eulerAngles.pitch, - eulerAngles.yaw - ); - - // 4. 使用六轴手眼转换(Eye-in-Hand模式)计算机器人目标位姿 - CCoordinateTransform::sixAxisEyeInHandCalcGraspPose(cameraPose, robotPose, handEye, targetPose); - - LOG_DEBUG("ConvertWorkpieceToRobotPose: Camera(%f, %f, %f, %f, %f, %f) -> Robot(%f, %f, %f, %f, %f, %f)\n", - cameraPose.x, cameraPose.y, cameraPose.z, - cameraPose.rx, cameraPose.ry, cameraPose.rz, - targetPose.x, targetPose.y, targetPose.z, - targetPose.rx, targetPose.ry, targetPose.rz); -} - -void WorkpieceHolePresenter::ConvertWorkpieceToRobotPoseEyeToHand(const WD_workpieceInfo& workpieceInfo, - const CTSixAxisCalibResult& cameraToBase, - CTRobotPose& targetPose) -{ - // 1. 从方向向量构建旋转矩阵 - CTRotationMatrix rotMatrix; - rotMatrix.at(0, 0) = workpieceInfo.x_dir.x; - rotMatrix.at(1, 0) = workpieceInfo.x_dir.y; - rotMatrix.at(2, 0) = workpieceInfo.x_dir.z; - rotMatrix.at(0, 1) = workpieceInfo.y_dir.x; - rotMatrix.at(1, 1) = workpieceInfo.y_dir.y; - rotMatrix.at(2, 1) = workpieceInfo.y_dir.z; - rotMatrix.at(0, 2) = workpieceInfo.z_dir.x; - rotMatrix.at(1, 2) = workpieceInfo.z_dir.y; - rotMatrix.at(2, 2) = workpieceInfo.z_dir.z; - - // 2. 将旋转矩阵转换为欧拉角 - CTEulerAngles eulerAngles = CCoordinateTransform::rotationMatrixToEuler(rotMatrix, CTEulerOrder::sZYX); - - // 3. 构造相机坐标系下的目标位姿 - CTCameraPose cameraPose( - workpieceInfo.center.x, - workpieceInfo.center.y, - workpieceInfo.center.z, - eulerAngles.roll, - eulerAngles.pitch, - eulerAngles.yaw - ); - - // 4. 使用六轴手眼转换(Eye-to-Hand模式)计算机器人目标位姿 - CCoordinateTransform::sixAxisEyeToHandCalcGraspPose(cameraPose, cameraToBase, targetPose); - - LOG_DEBUG("ConvertWorkpieceToRobotPoseEyeToHand: Camera(%f, %f, %f, %f, %f, %f) -> Robot(%f, %f, %f, %f, %f, %f)\n", - cameraPose.x, cameraPose.y, cameraPose.z, - cameraPose.rx, cameraPose.ry, cameraPose.rz, - targetPose.x, targetPose.y, targetPose.z, - targetPose.rx, targetPose.ry, targetPose.rz); -} - - void WorkpieceHolePresenter::CheckAndUpdateWorkStatus() { if (m_bCameraConnected) { diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Version.md b/App/WorkpieceHole/WorkpieceHoleApp/Version.md index 9e4ec6e..643db49 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Version.md +++ b/App/WorkpieceHole/WorkpieceHoleApp/Version.md @@ -1,6 +1,7 @@ # 1.1.0 ## build_0 2026-04-28 -1. 更新内存泄露问题 +1. 更新算法 +2. 更新内存泄露问题 # 1.0.3 ## build_0 2026-03-24 diff --git a/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro b/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro index c6d4f5f..fdf71a7 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro +++ b/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro @@ -42,6 +42,8 @@ INCLUDEPATH += $$PWD/../../../Module/AuthModule/Inc # 坐标变换库 INCLUDEPATH += $$PWD/../../../Utils/DataUtils/CoordinateTransform/Inc +# 手眼标定模块 +INCLUDEPATH += $$PWD/../../../Module/HandEyeCalib/Inc # eigen 依赖 INCLUDEPATH += $$PWD/../../../SDK/eigen-3.3.9 @@ -110,6 +112,7 @@ win32:CONFIG(debug, debug|release) { LIBS += -L../../../VrNets/debug -lVrModbus LIBS += -L../../../VrNets/debug -lVrTcpServer LIBS += -L../../../Utils/DataUtils/CoordinateTransform/debug -lCoordinateTransformd + LIBS += -L../../../Module/HandEyeCalib/debug -lHandEyeCalib }else:win32:CONFIG(release, debug|release){ LIBS += -L../../../Utils/VrUtils/release -lVrUtils @@ -126,6 +129,7 @@ win32:CONFIG(debug, debug|release) { LIBS += -L../../../VrNets/release -lVrModbus LIBS += -L../../../VrNets/release -lVrTcpServer LIBS += -L../../../Utils/DataUtils/CoordinateTransform/release -lCoordinateTransform + LIBS += -L../../../Module/HandEyeCalib/release -lHandEyeCalib }else:unix:!macx { # Unix/Linux平台库链接(包括交叉编译) # 注意链接顺序:依赖关系从高到低(被依赖的库放在后面) @@ -143,6 +147,7 @@ win32:CONFIG(debug, debug|release) { LIBS += -L../../../VrNets -lVrTcpServer LIBS += -L../../../Utils/VrUtils -lVrUtils LIBS += -L../../../Utils/DataUtils/CoordinateTransform -lCoordinateTransform + LIBS += -L../../../Module/HandEyeCalib -lHandEyeCalib # 添加系统库依赖 LIBS += -lpthread diff --git a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui index 94e9476..7adfb02 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui +++ b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui @@ -953,6 +953,19 @@ QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px; + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so index 50054bf..07d5d4a 100644 Binary files a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so and b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so differ diff --git a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libworkpieceHolePositioning.so index 84c7260..03fe659 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 53a67aa..456aaba 100644 --- a/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h +++ b/AppAlgo/workpieceHolePositioning/Inc/SG_baseDataType.h @@ -39,6 +39,13 @@ typedef struct SWD3DPoint point; }SWDIndexing3DPoint; +typedef struct +{ + int lineIdx; + int ptIdx; + SVzNL3DPoint point; +}SWDIndexingVzPoint; + typedef struct { int start; @@ -604,6 +611,7 @@ typedef struct double backwardDiffZ; double pre_stepDist; double post_stepDist; + double curr_z; double forward_z; double backward_z; }SSG_pntDirAngle; diff --git a/AppAlgo/workpieceHolePositioning/Inc/SG_errCode.h b/AppAlgo/workpieceHolePositioning/Inc/SG_errCode.h index 2b493b5..f3052b7 100644 --- a/AppAlgo/workpieceHolePositioning/Inc/SG_errCode.h +++ b/AppAlgo/workpieceHolePositioning/Inc/SG_errCode.h @@ -32,6 +32,10 @@ //ü߶Ȳ #define SX_ERR_INVALID_ARC -2301 +#define SX_ERR_INVALID_WHEEL_EDGE -2302 +#define SX_ERR_NO_WHEEL_COMMON_EDGE -2303 +#define SX_ERR_NO_WHEEL_ARC -2304 + //ǴӲ #define SX_ERR_NO_MARK -2401 diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll index b64f827..a8b817e 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 5506f9b..cd72fde 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 cf47283..46feed8 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 89e1a6b..5d8f213 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 8f6e253..fb3d710 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 2daf58c..561b9a4 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 733d9b3..06b0b2b 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 2138fcd..303abad 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/workpieceHolePositioning.pdb differ diff --git a/AppUtils/UICommon/AboutDialog.ui b/AppUtils/UICommon/AboutDialog.ui index 342278d..40af113 100644 --- a/AppUtils/UICommon/AboutDialog.ui +++ b/AppUtils/UICommon/AboutDialog.ui @@ -29,6 +29,9 @@ background-color: rgb(25, 26, 28); + + 6 + 40 @@ -41,15 +44,11 @@ 25 - - 6 - 22 - 75 true @@ -82,22 +81,6 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 10 - - - - @@ -109,32 +92,13 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 8 - - - - - - + 16 12 - - 1,4 - @@ -149,7 +113,7 @@ 机器码 - Qt::AlignRight|Qt::AlignVCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -185,7 +149,7 @@ CPU序列号 - Qt::AlignRight|Qt::AlignVCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -221,7 +185,7 @@ 硬盘序列号 - Qt::AlignRight|Qt::AlignVCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -257,7 +221,7 @@ 算法版本 - Qt::AlignRight|Qt::AlignVCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -301,6 +265,12 @@ Qt::Horizontal + + + 0 + 0 + + @@ -331,6 +301,12 @@ border-radius: 4px; Qt::Horizontal + + + 0 + 0 + + diff --git a/Module/HandEyeCalib/Inc/HandEyeCalibTypes.h b/Module/HandEyeCalib/Inc/HandEyeCalibTypes.h index c8b49f3..ed6df6b 100644 --- a/Module/HandEyeCalib/Inc/HandEyeCalibTypes.h +++ b/Module/HandEyeCalib/Inc/HandEyeCalibTypes.h @@ -392,6 +392,22 @@ struct HECCalibResult HECCalibResult() = default; + /** + * @brief 从4x4齐次变换矩阵(行优先double[16])构造标定结果 + * 提取旋转矩阵R(3x3)和平移向量T(3x1) + */ + static HECCalibResult fromHomogeneousArray(const double matrix[16]) + { + HECCalibResult result; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + result.R.at(i, j) = matrix[i * 4 + j]; + } + result.T.at(i) = matrix[i * 4 + 3]; + } + return result; + } + // 转换为齐次变换矩阵 HECHomogeneousMatrix toHomogeneousMatrix() const {