diff --git a/App/WorkpieceHole/Doc/MODBUS_PROTOCOL.md b/App/WorkpieceHole/Doc/MODBUS_PROTOCOL.md index 4a2f7d48..fd38ed4e 100644 --- a/App/WorkpieceHole/Doc/MODBUS_PROTOCOL.md +++ b/App/WorkpieceHole/Doc/MODBUS_PROTOCOL.md @@ -144,147 +144,3 @@ | 读å�–失败 | 记录日志,下次轮询é‡�试 | | 写入失败 | 记录日志,返回失败状æ€� | | è¶…æ—¶ | 默认1秒超时,触å�‘é‡�连 | - -## 8. é…�置文件 - -é…�置文件路径:`config/config.xml` - -```xml - -``` - -> **注æ„�**: robotServerIp 留空表示ä¸�使用机械臂直连 - -## 9. 代ç �接å�£ - -### 9.1 PLCModbusClient ç±» - -```cpp -// 寄存器地å�€é»˜è®¤å€¼ï¼ˆä»£ç �å��议地å�€ = D寄存器 + 1) -static constexpr int DEFAULT_ADDR_PHOTO_REQUEST = 1001; // D1000: æ‹�照请求 -static constexpr int DEFAULT_ADDR_DATA_COMPLETE = 1003; // D1002: æ•°æ�®å®Œæˆ� -static constexpr int DEFAULT_ADDR_COORD_DATA_START = 2001; // D2000: å��标数æ�®èµ·å§‹ - -// æ¯�个点å� ç”¨çš„寄存器数é‡�(6个float × 2寄存器/float = 12寄存器) -static constexpr int REGS_PER_POINT = 12; - -// 最大点数 -static constexpr int MAX_POINTS = 10; - -// å��标数æ�®ç»“构(float类型,大端åº�) -struct CoordinateData { - float x = 0.0f; // Xå��æ ‡ (mm) - float y = 0.0f; // Yå��æ ‡ (mm) - float z = 0.0f; // Zå��æ ‡ (mm) - float pitch = 0.0f; // Pitch角度 (°) - float roll = 0.0f; // Roll角度 (°) - float yaw = 0.0f; // Yaw角度 (°) -}; - -// åˆ�始化连接 -bool Initialize(const std::string& plcIP, int plcPort = 502, const RegisterConfig& regConfig = RegisterConfig()); - -// 关闭连接 -void Shutdown(); - -// å�¯åЍ/å�œæ­¢è½®è¯¢ -void StartPolling(int intervalMs = 100); -void StopPolling(); - -// 设置æ‹�照触å�‘回调 -void SetPhotoTriggerCallback(PhotoTriggerCallback callback); - -// 清除æ‹�照请求(写0到D1000) -bool ClearPhotoRequest(); - -// å�‘é€�å�•个å��标数æ�®åˆ°PLC(写入D2000开始) -bool SendCoordinateToPLC(const CoordinateData& coord, int pointIndex = 0); - -// å�‘é€�多个å��标数æ�®åˆ°PLC -bool SendCoordinatesToPLC(const std::vector& coords); - -// 通知数æ�®è¾“出完æˆ�(写1到D1002) -bool NotifyDataComplete(); - -// 连接状æ€�查询 -bool IsPLCConnected() const; -``` - -### 9.2 ä¿¡å�· - -```cpp -// æ‹�照请求信å�· -void photoRequested(int cameraIndex); - -// 连接状æ€�å�˜åŒ– -void connectionStateChanged(bool plcConnected); - -// 正在é‡�连 -void reconnecting(const QString& deviceName, int attemptCount); - -// 错误å�‘生 -void errorOccurred(const QString& errorMsg); -``` - -## 10. 使用示例 - -```cpp -// 创建客户端 -PLCModbusClient* client = new PLCModbusClient(this); - -// 从é…�置读å�–IPå¹¶åˆ�始化(å�ªè¿žæŽ¥PLC) -PLCModbusClient::RegisterConfig regConfig; -regConfig.addrPhotoRequest = 1001; // D1000 -regConfig.addrDataComplete = 1003; // D1002 -regConfig.addrCoordDataStart = 2001; // D2000 - -client->Initialize( - config.plcRobotServerConfig.plcServerIp, - config.plcRobotServerConfig.plcServerPort, - regConfig -); - -// 设置æ‹�照回调 -client->SetPhotoTriggerCallback([this, client](int cameraIndex) { - // 1. 清除æ‹�照请求 - client->ClearPhotoRequest(); - - // 2. 执行æ‹�照和算法 - auto results = doDetection(cameraIndex); - - // 3. å�‘é€�多个å��标点到PLC(D2000开始,float大端åº�) - std::vector coords; - for (const auto& result : results) { - PLCModbusClient::CoordinateData coord; - coord.x = result.x; // float (mm) - coord.y = result.y; // float (mm) - coord.z = result.z; // float (mm) - coord.pitch = result.pitch; // float (°) - coord.roll = result.roll; // float (°) - coord.yaw = result.yaw; // float (°) - coords.push_back(coord); - } - client->SendCoordinatesToPLC(coords); - - // 4. 通知完æˆ� - client->NotifyDataComplete(); -}); - -// å�¯åŠ¨è½®è¯¢ -client->StartPolling(100); - -// 程åº�退出时 -client->Shutdown(); -``` - -## 11. 版本历å�² - -| 版本 | 日期 | 说明 | -|------|------|------| -| 1.0 | 2025-01 | åˆ�始版本,支æŒ�PLC和机械臂 | -| 1.1 | 2025-01 | 移除机械臂直连,å��标数æ�®è¾“出到PLC | -| 1.2 | 2025-01 | å��标数æ�®æ”¹ä¸ºfloat大端åº�,支æŒ�最多10个点 | diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h index 5e21e233..6a99d91c 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/DetectPresenter.h @@ -31,6 +31,7 @@ public: LaserDataLoader& dataLoader, const double clibMatrix[16], int eulerOrder, + int dirVectorInvert, WorkpieceHoleDetectionResult& detectionResult); }; diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/PLCModbusClient.h b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/PLCModbusClient.h index 180d4b5f..8fad59b1 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/PLCModbusClient.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Inc/PLCModbusClient.h @@ -108,6 +108,7 @@ private: // 连接管ç�† bool checkConnection(); bool tryConnectPLC(); + void disconnectPLC(); // 主动断开连接(用于触å�‘é‡�连) // 寄存器æ“�作 int readPhotoRequest(); diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp index d4abb466..65eb489d 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/DetectPresenter.cpp @@ -1,9 +1,11 @@ #include "DetectPresenter.h" #include "workpieceHolePositioning_Export.h" +#include "SG_baseAlgo_Export.h" #include #include #include #include +#include #include "CoordinateTransform.h" #include "VrConvert.h" @@ -25,6 +27,7 @@ int DetectPresenter::DetectWorkpieceHole( LaserDataLoader& dataLoader, const double clibMatrix[16], int eulerOrder, + int dirVectorInvert, WorkpieceHoleDetectionResult& detectionResult) { if (laserLines.empty()) { @@ -173,9 +176,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é½�次å�˜æ�¢çŸ©é˜µï¼Œé�¿å…�欧拉角转æ�¢è¯¯å·® - CTHomogeneousMatrix calibHMatrix; - memcpy(calibHMatrix.data, clibMatrix, sizeof(double) * 16); + // 从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::vector> objOps; @@ -192,47 +202,72 @@ int DetectPresenter::DetectWorkpieceHole( // 六轴转æ�¢ï¼šä½�ç½®+å§¿æ€�(转æ�¢åˆ°æœºæ¢°è‡‚å��标系) SVzNL3DPoint centerEye = workpiece.center; - // 从方å�‘å�‘é‡�构建旋转矩阵 - // 算法输出的 x_dir, y_dir, z_dir 是工件å��标系的三个轴在相机å��标系下的方å�‘ - CTRotationMatrix rotMatrix; - // 第一列:Xè½´æ–¹å�‘ - rotMatrix.at(0, 0) = workpiece.x_dir.x; - rotMatrix.at(1, 0) = workpiece.x_dir.y; - rotMatrix.at(2, 0) = workpiece.x_dir.z; - // 第二列:Yè½´æ–¹å�‘ - rotMatrix.at(0, 1) = workpiece.y_dir.x; - rotMatrix.at(1, 1) = workpiece.y_dir.y; - rotMatrix.at(2, 1) = workpiece.y_dir.z; - // 第三列:Zè½´æ–¹å�‘ - rotMatrix.at(0, 2) = workpiece.z_dir.x; - rotMatrix.at(1, 2) = workpiece.z_dir.y; - rotMatrix.at(2, 2) = workpiece.z_dir.z; + // 1. ä½�置转æ�¢ï¼šä½¿ç”¨ pointRT_2 进行å��æ ‡å�˜æ�¢ + cv::Point3d ptEye(centerEye.x, centerEye.y, centerEye.z); + cv::Point3d ptRobot; + pointRT_2(R, T, ptEye, ptRobot); - // 将旋转矩阵转æ�¢ä¸ºæ¬§æ‹‰è§’(使用é…�置的旋转顺åº�) - CTEulerAngles eulerAngles = CCoordinateTransform::rotationMatrixToEuler(rotMatrix, static_cast(eulerOrder)); + // 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); - // 构建相机å��标系下的完整ä½�å§¿ - CTCameraPose cameraPose; - cameraPose.x = centerEye.x; - cameraPose.y = centerEye.y; - cameraPose.z = centerEye.z; - cameraPose.rx = eulerAngles.roll; - cameraPose.ry = eulerAngles.pitch; - cameraPose.rz = eulerAngles.yaw; + // æ ¹æ�®é…�置决定方å�‘å�‘é‡�å��å�‘ + 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); + 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); + 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); + break; + } - // 进行六轴Eye-to-Hand转æ�¢ï¼ˆä½�ç½®+å§¿æ€�) - // 使用é…�置的旋转顺åº� - CTRobotPose robotPose; - CCoordinateTransform::sixAxisEyeToHandCalcGraspPose(cameraPose, calibHMatrix, static_cast(eulerOrder), robotPose); + // 使用 pointRotate 对方å�‘å�‘é‡�进行旋转å�˜æ�¢ + std::vector dirVectors_robot; + for (int j = 0; j < 3; j++) { + cv::Point3d rt_pt; + pointRotate(R, dirVectors_eye[j], rt_pt); + dirVectors_robot.push_back(rt_pt); + } + + // 3. 构建旋转矩阵(按照测试代ç �的方å¼�) + double R_pose[3][3]; + R_pose[0][0] = dirVectors_robot[0].x; + R_pose[0][1] = dirVectors_robot[1].x; + R_pose[0][2] = dirVectors_robot[2].x; + R_pose[1][0] = dirVectors_robot[0].y; + R_pose[1][1] = dirVectors_robot[1].y; + R_pose[1][2] = dirVectors_robot[2].y; + R_pose[2][0] = dirVectors_robot[0].z; + R_pose[2][1] = dirVectors_robot[1].z; + R_pose[2][2] = dirVectors_robot[2].z; + + // 4. 使用 rotationMatrixToEulerZYX 转æ�¢ä¸ºæ¬§æ‹‰è§’(外旋ZYX,å�³RZ-RY-RX) + SSG_EulerAngles robotRpy = rotationMatrixToEulerZYX(R_pose); // 将机器人å��标系下的ä½�姿添加到positions列表 HolePosition centerRobotPos; - centerRobotPos.x = robotPose.x; - centerRobotPos.y = robotPose.y; - centerRobotPos.z = robotPose.z; - centerRobotPos.roll = CCoordinateTransform::radToDeg(robotPose.rx); - centerRobotPos.pitch = CCoordinateTransform::radToDeg(robotPose.ry); - centerRobotPos.yaw = CCoordinateTransform::radToDeg(robotPose.rz); + centerRobotPos.x = ptRobot.x; + centerRobotPos.y = ptRobot.y; + centerRobotPos.z = ptRobot.z; + centerRobotPos.roll = robotRpy.roll; // å·²ç»�是角度 + centerRobotPos.pitch = robotRpy.pitch; // å·²ç»�是角度 + centerRobotPos.yaw = robotRpy.yaw; // å·²ç»�是角度 detectionResult.positions.push_back(centerRobotPos); @@ -246,16 +281,19 @@ int DetectPresenter::DetectWorkpieceHole( objOps.push_back(holePoints); if(debugParam.enableDebug && debugParam.printDetailLog){ - LOG_INFO("[Algo Thread] Direction vectors: X=(%.3f,%.3f,%.3f), Y=(%.3f,%.3f,%.3f), Z=(%.3f,%.3f,%.3f)\n", + 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, workpiece.y_dir.x, workpiece.y_dir.y, workpiece.y_dir.z, workpiece.z_dir.x, workpiece.z_dir.y, workpiece.z_dir.z); - LOG_INFO("[Algo Thread] Center Eye Coords: X=%.2f, Y=%.2f, Z=%.2f, R=%.4f, P=%.4f, Y=%.4f\n", - cameraPose.x, cameraPose.y, cameraPose.z, - CCoordinateTransform::radToDeg(cameraPose.rx), CCoordinateTransform::radToDeg(cameraPose.ry), CCoordinateTransform::radToDeg(cameraPose.rz)); + LOG_INFO("[Algo Thread] Direction vectors (robot): X=(%.3f,%.3f,%.3f), Y=(%.3f,%.3f,%.3f), Z=(%.3f,%.3f,%.3f)\n", + 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", - robotPose.x, robotPose.y, robotPose.z, - CCoordinateTransform::radToDeg(robotPose.rx), CCoordinateTransform::radToDeg(robotPose.ry), CCoordinateTransform::radToDeg(robotPose.rz)); + ptRobot.x, ptRobot.y, ptRobot.z, + centerRobotPos.roll, centerRobotPos.pitch, centerRobotPos.yaw); } } diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/PLCModbusClient.cpp b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/PLCModbusClient.cpp index 61e64125..e7570523 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/PLCModbusClient.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/PLCModbusClient.cpp @@ -240,6 +240,10 @@ void PLCModbusClient::pollThreadFunc() notifyPhotoRequested(1); } m_lastPhotoRequestState = currentState; + } else { + // 读å�–失败,å�¯èƒ½æ˜¯è¿žæŽ¥æ–­å¼€ï¼Œä¸»åŠ¨æ–­å¼€è¿žæŽ¥ä»¥è§¦å�‘é‡�连 + LOG_WARNING("Failed to read photo request, disconnecting to trigger reconnect\n"); + disconnectPLC(); } std::this_thread::sleep_for(std::chrono::milliseconds(m_pollIntervalMs)); @@ -277,6 +281,16 @@ bool PLCModbusClient::tryConnectPLC() return true; } +void PLCModbusClient::disconnectPLC() +{ + std::lock_guard locker(m_mutex); + + if (m_plcClient) { + m_plcClient->Disconnect(); + LOG_INFO("PLC disconnected for reconnection\n"); + } +} + int PLCModbusClient::readPhotoRequest() { std::lock_guard locker(m_mutex); diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp index c3ef9653..84de85dc 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/Presenter/Src/WorkpieceHolePresenter.cpp @@ -380,11 +380,15 @@ int WorkpieceHolePresenter::ProcessAlgoDetection(std::vectorDetectWorkpieceHole(m_currentCameraIndex, detectionDataCache, algorithmParams, debugParam, m_dataLoader, - currentClibMatrix.clibMatrix, eulerOrder, detectionResult); + currentClibMatrix.clibMatrix, eulerOrder, dirVectorInvert, detectionResult); // æ ¹æ�®é¡¹ç›®ç±»åž‹é€‰æ‹©å¤„ç�†æ–¹å¼� if (GetStatusCallback()) { QString err = QString("错误:%1").arg(nRet); @@ -729,8 +733,9 @@ int WorkpieceHolePresenter::InitPLCModbus() LOG_INFO("PLC connection state changed: PLC=%s\n", plcConnected ? "connected" : "disconnected"); - // 通知 UI 更新连接状æ€� + // 通知 UI 更新连接状æ€�(PLC连接状æ€�å…³è�”到机械臂状æ€�指示器) if (auto pStatus = GetStatusCallback()) { + pStatus->OnRobotConnectionChanged(plcConnected); std::string statusMsg = std::string("PLC:") + (plcConnected ? "已连接" : "æ–­å¼€"); pStatus->OnStatusUpdate(statusMsg); } @@ -743,6 +748,15 @@ int WorkpieceHolePresenter::InitPLCModbus() } }); + // 设置é‡�连回调,通知用户正在å°�试é‡�连 + m_pPLCModbusClient->SetReconnectingCallback([this](const std::string& device, int attempt) { + LOG_INFO("Attempting to reconnect %s (attempt %d)\n", device.c_str(), attempt); + if (auto pStatus = GetStatusCallback()) { + std::string statusMsg = device + "正在é‡�连(第" + std::to_string(attempt) + "次)..."; + pStatus->OnStatusUpdate(statusMsg); + } + }); + // 构建寄存器地å�€é…�ç½® PLCModbusClient::RegisterConfig regConfig; regConfig.addrPhotoRequest = configResult.plcRobotServerConfig.registerConfig.addrPhotoRequest; @@ -825,6 +839,11 @@ void WorkpieceHolePresenter::SendCoordinateDataToPLC(const WorkpieceHoleDetectio return; } + // 获å�–å§¿æ€�输出顺åº�é…�ç½® + ConfigResult configResult = m_pConfigManager->GetConfigResult(); + int poseOutputOrder = configResult.plcRobotServerConfig.poseOutputOrder; + LOG_INFO("Using pose output order: %d\n", poseOutputOrder); + // 构建å��标数æ�®åˆ—表(æ¯�个工件的中心点+å§¿æ€�,最多10个) std::vector coords; int pointCount = std::min(static_cast(result.positions.size()), PLCModbusClient::MAX_POINTS); @@ -837,13 +856,50 @@ void WorkpieceHolePresenter::SendCoordinateDataToPLC(const WorkpieceHoleDetectio coord.x = static_cast(pos.x); coord.y = static_cast(pos.y); coord.z = static_cast(pos.z); - coord.roll = static_cast(pos.roll); - coord.pitch = static_cast(pos.pitch); - coord.yaw = static_cast(pos.yaw); + + // æ ¹æ�®å§¿æ€�输出顺åº�é…�置调整输出 + switch (poseOutputOrder) { + case POSE_ORDER_RPY: // Roll, Pitch, Yaw(默认) + coord.roll = static_cast(pos.roll); + coord.pitch = static_cast(pos.pitch); + coord.yaw = static_cast(pos.yaw); + break; + case POSE_ORDER_RYP: // Roll, Yaw, Pitch + coord.roll = static_cast(pos.roll); + coord.pitch = static_cast(pos.yaw); + coord.yaw = static_cast(pos.pitch); + break; + case POSE_ORDER_PRY: // Pitch, Roll, Yaw + coord.roll = static_cast(pos.pitch); + coord.pitch = static_cast(pos.roll); + coord.yaw = static_cast(pos.yaw); + break; + case POSE_ORDER_PYR: // Pitch, Yaw, Roll + coord.roll = static_cast(pos.pitch); + coord.pitch = static_cast(pos.yaw); + coord.yaw = static_cast(pos.roll); + break; + case POSE_ORDER_YRP: // Yaw, Roll, Pitch + coord.roll = static_cast(pos.yaw); + coord.pitch = static_cast(pos.roll); + coord.yaw = static_cast(pos.pitch); + break; + case POSE_ORDER_YPR: // Yaw, Pitch, Roll + coord.roll = static_cast(pos.yaw); + coord.pitch = static_cast(pos.pitch); + coord.yaw = static_cast(pos.roll); + break; + default: // 默认 RPY + coord.roll = static_cast(pos.roll); + coord.pitch = static_cast(pos.pitch); + coord.yaw = static_cast(pos.yaw); + break; + } coords.push_back(coord); - LOG_INFO("Workpiece[%d]: X=%.2f, Y=%.2f, Z=%.2f, P=%.2f, R=%.2f, Y=%.2f\n", i, coord.x, coord.y, coord.z, coord.roll, coord.pitch, coord.yaw); + LOG_INFO("Workpiece[%d]: X=%.2f, Y=%.2f, Z=%.2f, R1=%.2f, R2=%.2f, R3=%.2f (order=%d)\n", + i, coord.x, coord.y, coord.z, coord.roll, coord.pitch, coord.yaw, poseOutputOrder); } LOG_INFO("Sending %d workpiece positions to PLC\n", pointCount); diff --git a/App/WorkpieceHole/WorkpieceHoleApp/Version.h b/App/WorkpieceHole/WorkpieceHoleApp/Version.h index c0a1f52d..8066616c 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Version.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/Version.h @@ -3,7 +3,7 @@ // 版本字符串 #define WORKPIECEHOLE_VERSION_STRING "1.0.1" -#define WORKPIECEHOLE_BUILD_STRING "2" +#define WORKPIECEHOLE_BUILD_STRING "5" #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 8edbb191..850c184e 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/Version.md +++ b/App/WorkpieceHole/WorkpieceHoleApp/Version.md @@ -1,4 +1,10 @@ # 1.0.1 +## build_4 +1. 增加了å��议姿æ€�输出顺åº� + +## build_3 2026-02-01 +1. 更新了算法,输出的姿æ€� + ## build_2 2026-02-01 1. å��议测试修正 diff --git a/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro b/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro index e2625c61..11a14436 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro +++ b/App/WorkpieceHole/WorkpieceHoleApp/WorkpieceHoleApp.pro @@ -4,7 +4,7 @@ QT += core gui network serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -CONFIG += c++17 +CONFIG += c++11 # 项目å��ç§° TARGET = WorkpieceHoleApp @@ -44,6 +44,10 @@ INCLUDEPATH += $$PWD/../../../DataUtils/CoordinateTransform/Inc # eigen ä¾�èµ– INCLUDEPATH += $$PWD/../../../SDK/eigen-3.3.9 +#opencv +INCLUDEPATH += $$PWD/../../../SDK/OpenCV320/include + + # ModbusTCP 客户端库(å�ªåŒ…å�«å¯¼å‡ºæŽ¥å�£ç›®å½•,ä¸�包å�«å†…部 modbus 头文件) INCLUDEPATH += $$PWD/../../../Module/ModbusTCPClient/Inc diff --git a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.cpp b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.cpp index cc0d53f4..0dda9be8 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.cpp +++ b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.cpp @@ -38,6 +38,12 @@ DialogAlgoarg::DialogAlgoarg(ConfigManager* configManager, QWidget *parent) // åˆ�始化旋转顺åº�下拉框 InitEulerOrderComboBox(); + // åˆ�始化姿æ€�输出顺åº�下拉框 + InitPoseOutputOrderComboBox(); + + // åˆ�始化方å�‘å�‘é‡�å��å�‘下拉框 + InitDirVectorInvertComboBox(); + // 从é…�置文件加载数æ�®åˆ°ç•Œé�¢ LoadConfigToUI(); @@ -387,19 +393,56 @@ void DialogAlgoarg::InitEulerOrderComboBox() ui->comboBox_eulerOrder->setCurrentIndex(0); } +void DialogAlgoarg::InitPoseOutputOrderComboBox() +{ + // 添加姿æ€�输出顺åº�选项 + ui->comboBox_poseOutputOrder->addItem("RPY (Roll, Pitch, Yaw)", POSE_ORDER_RPY); // 默认 + ui->comboBox_poseOutputOrder->addItem("RYP (Roll, Yaw, Pitch)", POSE_ORDER_RYP); + ui->comboBox_poseOutputOrder->addItem("PRY (Pitch, Roll, Yaw)", POSE_ORDER_PRY); + ui->comboBox_poseOutputOrder->addItem("PYR (Pitch, Yaw, Roll)", POSE_ORDER_PYR); + ui->comboBox_poseOutputOrder->addItem("YRP (Yaw, Roll, Pitch)", POSE_ORDER_YRP); + ui->comboBox_poseOutputOrder->addItem("YPR (Yaw, Pitch, Roll)", POSE_ORDER_YPR); + + // 默认选择 RPY + ui->comboBox_poseOutputOrder->setCurrentIndex(0); +} + +void DialogAlgoarg::InitDirVectorInvertComboBox() +{ + // 添加方å�‘å�‘é‡�å��å�‘选项 + ui->comboBox_dirVectorInvert->addItem("ä¸�å��å�‘", DIR_INVERT_NONE); + ui->comboBox_dirVectorInvert->addItem("XYå��å�‘", DIR_INVERT_XY); + ui->comboBox_dirVectorInvert->addItem("XZå��å�‘", DIR_INVERT_XZ); + ui->comboBox_dirVectorInvert->addItem("YZå��å�‘(默认)", DIR_INVERT_YZ); + + // 默认选择 YZå��å�‘(兼容原有行为) + ui->comboBox_dirVectorInvert->setCurrentIndex(3); +} + void DialogAlgoarg::LoadPlcRobotServerConfigToUI(const VrPlcRobotServerConfig& config) { if (!ui) return; + // 加载PLCæœ�务端é…�ç½® ui->lineEdit_plcServerIp->setText(QString::fromStdString(config.plcServerIp)); ui->lineEdit_plcServerPort->setText(QString::number(config.plcServerPort)); - ui->lineEdit_robotServerIp->setText(QString::fromStdString(config.robotServerIp)); - ui->lineEdit_robotServerPort->setText(QString::number(config.robotServerPort)); // 加载PLC寄存器地å�€é…�ç½® ui->lineEdit_addrPhotoRequest->setText(QString::number(config.registerConfig.addrPhotoRequest)); ui->lineEdit_addrDataComplete->setText(QString::number(config.registerConfig.addrDataComplete)); ui->lineEdit_addrCoordDataStart->setText(QString::number(config.registerConfig.addrCoordDataStart)); + + // 加载姿æ€�输出顺åº� + int poseOrderIndex = ui->comboBox_poseOutputOrder->findData(config.poseOutputOrder); + if (poseOrderIndex >= 0) { + ui->comboBox_poseOutputOrder->setCurrentIndex(poseOrderIndex); + } + + // 加载方å�‘å�‘é‡�å��å�‘é…�ç½® + int dirInvertIndex = ui->comboBox_dirVectorInvert->findData(config.dirVectorInvert); + if (dirInvertIndex >= 0) { + ui->comboBox_dirVectorInvert->setCurrentIndex(dirInvertIndex); + } } bool DialogAlgoarg::SavePlcRobotServerConfigFromUI(VrPlcRobotServerConfig& config) @@ -420,19 +463,6 @@ bool DialogAlgoarg::SavePlcRobotServerConfigFromUI(VrPlcRobotServerConfig& confi return false; } - // 获å�–机械臂æœ�务端IP - QString robotIp = ui->lineEdit_robotServerIp->text().trimmed(); - if (robotIp.isEmpty()) { - return false; - } - config.robotServerIp = robotIp.toStdString(); - - // 获å�–机械臂æœ�务端端å�£ - config.robotServerPort = ui->lineEdit_robotServerPort->text().toInt(&ok); - if (!ok || config.robotServerPort <= 0 || config.robotServerPort > 65535) { - return false; - } - // 获å�–PLC寄存器地å�€é…�ç½® config.registerConfig.addrPhotoRequest = ui->lineEdit_addrPhotoRequest->text().toInt(&ok); if (!ok || config.registerConfig.addrPhotoRequest < 0) { @@ -449,5 +479,11 @@ bool DialogAlgoarg::SavePlcRobotServerConfigFromUI(VrPlcRobotServerConfig& confi return false; } + // 获å�–å§¿æ€�输出顺åº� + config.poseOutputOrder = ui->comboBox_poseOutputOrder->currentData().toInt(); + + // 获å�–æ–¹å�‘å�‘é‡�å��å�‘é…�ç½® + config.dirVectorInvert = ui->comboBox_dirVectorInvert->currentData().toInt(); + return true; } diff --git a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.h b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.h index ed6e7ab8..35ab1a7f 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.h +++ b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.h @@ -40,9 +40,11 @@ private: bool SaveFilterParamFromUI(VrOutlierFilterParam& param); bool SaveGrowParamFromUI(VrTreeGrowParam& param); - // 网络é…�置(PLC和机械臂æœ�务端) + // 网络é…�置(PLCæœ�务端) void LoadPlcRobotServerConfigToUI(const VrPlcRobotServerConfig& config); bool SavePlcRobotServerConfigFromUI(VrPlcRobotServerConfig& config); + void InitPoseOutputOrderComboBox(); + void InitDirVectorInvertComboBox(); // 手眼标定矩阵 void LoadCalibMatrixToUI(); diff --git a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui index aa5aa1cc..e2283f98 100644 --- a/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui +++ b/App/WorkpieceHole/WorkpieceHoleApp/dialogalgoarg.ui @@ -62,7 +62,7 @@ QGroupBox { color: rgb(221, 225, 233); border: 1px solid rgb(100, 100, 100); bor QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px; } - 0 + 5 @@ -809,7 +809,7 @@ QComboBox QAbstractItemView { 10 20 671 - 251 + 291 @@ -826,7 +826,7 @@ QComboBox QAbstractItemView { 20 40 631 - 200 + 246 @@ -950,106 +950,120 @@ QComboBox QAbstractItemView { - - - - - - - 10 - 290 - 671 - 201 - - - - - 16 - - - - 机械臂æœ�务端é…�ç½® - - - - - 20 - 40 - 631 - 148 - - - - - + + - 16 + 14 - 机械臂æœ�务端IP地å�€ + å§¿æ€�输出顺åº� - - + + - 16 + 14 - - 例如: 192.168.1.20 + + QComboBox { + background-color: rgb(50, 52, 56); + color: rgb(221, 225, 233); + border: 1px solid rgb(80, 82, 86); + border-radius: 4px; + padding: 5px; +} +QComboBox::drop-down { + border: none; +} +QComboBox QAbstractItemView { + background-color: rgb(50, 52, 56); + color: rgb(221, 225, 233); + selection-background-color: rgb(60, 120, 180); +} - - + + - 16 + 14 - 机械臂æœ�务端端å�£ + æ–¹å�‘å�‘é‡�å��å�‘ - - + + - 16 + 14 - - 例如: 502 + + QComboBox { + background-color: rgb(50, 52, 56); + color: rgb(221, 225, 233); + border: 1px solid rgb(80, 82, 86); + border-radius: 4px; + padding: 5px; +} +QComboBox::drop-down { + border: none; +} +QComboBox QAbstractItemView { + background-color: rgb(50, 52, 56); + color: rgb(221, 225, 233); + selection-background-color: rgb(60, 120, 180); +} - + - + - 190 + 2 670 - 100 - 45 + 751 + 44 - - - 16 - true - - - - QPushButton { + + + + + Qt::Horizontal + + + + 178 + 20 + + + + + + + + + 16 + true + + + + QPushButton { background-color: rgb(60, 120, 180); color: rgb(221, 225, 233); border: none; @@ -1062,28 +1076,35 @@ QPushButton:hover { QPushButton:pressed { background-color: rgb(40, 100, 160); } - - - ä¿�å­˜ - - - - - - 410 - 670 - 100 - 45 - - - - - 16 - true - - - - QPushButton { + + + ä¿�å­˜ + + + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + + 16 + true + + + + QPushButton { background-color: rgb(120, 120, 120); color: rgb(221, 225, 233); border: none; @@ -1096,10 +1117,26 @@ QPushButton:hover { QPushButton:pressed { background-color: rgb(100, 100, 100); } - - - å�–消 - + + + å�–消 + + + + + + + Qt::Horizontal + + + + 178 + 20 + + + + + diff --git a/App/WorkpieceHole/WorkpieceHoleConfig/Inc/IVrConfig.h b/App/WorkpieceHole/WorkpieceHoleConfig/Inc/IVrConfig.h index 7bc0c3da..6687b6a7 100644 --- a/App/WorkpieceHole/WorkpieceHoleConfig/Inc/IVrConfig.h +++ b/App/WorkpieceHole/WorkpieceHoleConfig/Inc/IVrConfig.h @@ -107,6 +107,35 @@ struct VrPlcRegisterConfig VrPlcRegisterConfig() = default; }; +/** + * @brief å§¿æ€�输出顺åº�枚举 + * + * 定义机械臂姿æ€�æ•°æ�®çš„输出顺åº� + */ +enum VrPoseOutputOrder +{ + POSE_ORDER_RPY = 0, // Roll, Pitch, Yaw(默认) + POSE_ORDER_RYP = 1, // Roll, Yaw, Pitch + POSE_ORDER_PRY = 2, // Pitch, Roll, Yaw + POSE_ORDER_PYR = 3, // Pitch, Yaw, Roll + POSE_ORDER_YRP = 4, // Yaw, Roll, Pitch + POSE_ORDER_YPR = 5 // Yaw, Pitch, Roll +}; + +/** + * @brief æ–¹å�‘å�‘é‡�å��å�‘é…�置枚举 + * + * 定义机械臂方å�‘å�‘é‡�çš„å��å�‘é…�ç½® + * 用于调整相机å��标系到机械臂å��标系的方å�‘å�‘é‡�转æ�¢ + */ +enum VrDirVectorInvert +{ + DIR_INVERT_NONE = 0, // ä¸�å��å�‘ + DIR_INVERT_XY = 1, // Xå’ŒYæ–¹å�‘å��å�‘ + DIR_INVERT_XZ = 2, // Xå’ŒZæ–¹å�‘å��å�‘ + DIR_INVERT_YZ = 3 // Yå’ŒZæ–¹å�‘å��å�‘(默认,兼容原有行为) +}; + /** * @brief PLC和机械臂æœ�务端é…�ç½® * @@ -121,6 +150,8 @@ struct VrPlcRobotServerConfig std::string robotServerIp = "192.168.0.90"; // 机械臂æœ�务端IP地å�€ï¼ˆé…�天机械臂) int robotServerPort = 502; // 机械臂æœ�务端端å�£ï¼ˆModbus TCP默认502) VrPlcRegisterConfig registerConfig; // PLC 寄存器地å�€é…�ç½® + int poseOutputOrder = POSE_ORDER_RPY; // å§¿æ€�输出顺åº�,默认RPY + int dirVectorInvert = DIR_INVERT_YZ; // æ–¹å�‘å�‘é‡�å��å�‘é…�置,默认YZå��å�‘(兼容原有行为) // 显å¼�赋值构造函数 VrPlcRobotServerConfig& operator=(const VrPlcRobotServerConfig& other) { @@ -130,6 +161,8 @@ struct VrPlcRobotServerConfig robotServerIp = other.robotServerIp; robotServerPort = other.robotServerPort; registerConfig = other.registerConfig; + poseOutputOrder = other.poseOutputOrder; + dirVectorInvert = other.dirVectorInvert; } return *this; } @@ -140,7 +173,9 @@ struct VrPlcRobotServerConfig , plcServerPort(other.plcServerPort) , robotServerIp(other.robotServerIp) , robotServerPort(other.robotServerPort) - , registerConfig(other.registerConfig) { + , registerConfig(other.registerConfig) + , poseOutputOrder(other.poseOutputOrder) + , dirVectorInvert(other.dirVectorInvert) { } // 默认构造函数 diff --git a/App/WorkpieceHole/WorkpieceHoleConfig/Src/VrConfig.cpp b/App/WorkpieceHole/WorkpieceHoleConfig/Src/VrConfig.cpp index 38e4265e..1bd93ff0 100644 --- a/App/WorkpieceHole/WorkpieceHoleConfig/Src/VrConfig.cpp +++ b/App/WorkpieceHole/WorkpieceHoleConfig/Src/VrConfig.cpp @@ -274,6 +274,18 @@ int CVrConfig::LoadConfig(const std::string& filePath, ConfigResult& configResul configResult.plcRobotServerConfig.registerConfig.addrDataComplete = tcpServerConfigElement->IntAttribute("addrDataComplete"); if (tcpServerConfigElement->Attribute("addrCoordDataStart")) configResult.plcRobotServerConfig.registerConfig.addrCoordDataStart = tcpServerConfigElement->IntAttribute("addrCoordDataStart"); + + // è§£æž�å§¿æ€�输出顺åº�é…�ç½® + if (tcpServerConfigElement->Attribute("poseOutputOrder")) + configResult.plcRobotServerConfig.poseOutputOrder = tcpServerConfigElement->IntAttribute("poseOutputOrder"); + else + configResult.plcRobotServerConfig.poseOutputOrder = POSE_ORDER_RPY; // 默认RPY + + // è§£æž�æ–¹å�‘å�‘é‡�å��å�‘é…�ç½® + if (tcpServerConfigElement->Attribute("dirVectorInvert")) + configResult.plcRobotServerConfig.dirVectorInvert = tcpServerConfigElement->IntAttribute("dirVectorInvert"); + else + configResult.plcRobotServerConfig.dirVectorInvert = DIR_INVERT_YZ; // 默认YZå��å�‘(兼容原有行为) } return LOAD_CONFIG_SUCCESS; @@ -431,6 +443,10 @@ bool CVrConfig::SaveConfig(const std::string& filePath, ConfigResult& configResu tcpServerConfigElement->SetAttribute("addrPhotoRequest", configResult.plcRobotServerConfig.registerConfig.addrPhotoRequest); tcpServerConfigElement->SetAttribute("addrDataComplete", configResult.plcRobotServerConfig.registerConfig.addrDataComplete); tcpServerConfigElement->SetAttribute("addrCoordDataStart", configResult.plcRobotServerConfig.registerConfig.addrCoordDataStart); + // ä¿�存姿æ€�输出顺åº�é…�ç½® + tcpServerConfigElement->SetAttribute("poseOutputOrder", configResult.plcRobotServerConfig.poseOutputOrder); + // ä¿�存方å�‘å�‘é‡�å��å�‘é…�ç½® + tcpServerConfigElement->SetAttribute("dirVectorInvert", configResult.plcRobotServerConfig.dirVectorInvert); root->InsertEndChild(tcpServerConfigElement); // ä¿�存到文件 diff --git a/App/WorkpieceHole/WorkpieceHoleConfig/config/config.xml b/App/WorkpieceHole/WorkpieceHoleConfig/config/config.xml index b0e1b966..a9a4a5c6 100644 --- a/App/WorkpieceHole/WorkpieceHoleConfig/config/config.xml +++ b/App/WorkpieceHole/WorkpieceHoleConfig/config/config.xml @@ -24,5 +24,5 @@ - + diff --git a/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so b/AppAlgo/workpieceHolePositioning/Arm/aarch64/libbaseAlgorithm.so index f72ae99a..ca3a5326 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 9c2ab543..3ac8d924 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_baseAlgo_Export.h b/AppAlgo/workpieceHolePositioning/Inc/SG_baseAlgo_Export.h new file mode 100644 index 00000000..cca6972f --- /dev/null +++ b/AppAlgo/workpieceHolePositioning/Inc/SG_baseAlgo_Export.h @@ -0,0 +1,755 @@ +#pragma once + +#include "SG_algo_Export.h" +#include +#include + + +//Â˳ýÀëȺµã:zÌø±äÃÅÏÞ·½·¨£¨´óÓÚÃÅÏÞÊÓΪ²»Á¬Ðø£¬¸ù¾ÝÁ¬Ðø¶ÎµãÊýÁ¿ÅжÏÔëÉù£© +SG_APISHARED_EXPORT void sg_lineDataRemoveOutlier( + SVzNL3DPosition* lineData, + int dataSize, + SSG_outlierFilterParam filterParam, + std::vector& filerData, + std::vector& noisePts); +//Â˳ýÀëȺµã£ºzÌø±äÃÅÏÞ·½·¨,¸Ä±äԭʼÊý¾Ý +SG_APISHARED_EXPORT void sg_lineDataRemoveOutlier_changeOriginData( + SVzNL3DPosition* lineData, + int dataSize, + SSG_outlierFilterParam filterParam); +//Â˳ýÀëȺµã£ºzÌø±äÃÅÏÞ·½·¨, vecotr¶ÔÏó +SG_APISHARED_EXPORT void wd_vectorDataRemoveOutlier_overwrite( + std::vector& a_line, + SSG_outlierFilterParam filterParam); +//Â˳ýÀëȺµã£ºµã¾àÀëÃÅÏÞ·½·¨£¨´óÓÚÃÅÏÞÊÓΪ²»Á¬Ðø£¬¸ù¾ÝÁ¬Ðø¶ÎµãÊýÁ¿ÅжÏÔëÉù£© +SG_APISHARED_EXPORT void sg_lineDataRemoveOutlier_ptDistMethod( + SVzNL3DPosition* lineData, + int dataSize, + SSG_outlierFilterParam filterParam, + std::vector& filerData, + std::vector& noisePts); + +//ƽ»¬ +SG_APISHARED_EXPORT void sg_lineDataSmoothing( + std::vector& input, + int smoothWin, + std::vector& output); +//·Ö¶Îƽ»¬£¬ÕâÑù²»»áÓ°Ïì·Ö¶Î¶Ëµã +SG_APISHARED_EXPORT void sg_lineSegSmoothing( + std::vector& input, + double seg_y_deltaTh, //·Ö¶ÎµÄY¼ä¸ô¡£´óÓڴ˼ä¸ô£¬ÎªÐµķֶΠ+ double seg_z_deltaTh,//·Ö¶ÎµÄZ¼ä¸ô¡£´óÓڴ˼ä¸ô£¬ÎªÐµķֶΠ+ int smoothWin, + std::vector& output); + +//VZ_APISHARED_EXPORT void sg_getLineMeanVar(); +SG_APISHARED_EXPORT void sg_getLineLVFeature( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const SSG_slopeParam slopeParam, + const SSG_VFeatureParam valleyPara, + SSG_lineFeature* line_features); + +//»ñȡɨÃèÏß¹ÕµãÌØÕ÷ +SG_APISHARED_EXPORT void sg_getLineCornerFeature( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const SSG_cornerParam cornerPara, //scaleͨ³£È¡bagHµÄ1/4 + SSG_lineFeature* line_features); + +// ¶Ô¼¤¹âÏßÉÏÓÉMask(nPointIdxתÒ嶨Ò壩ָ¶¨µÄµãÌáÈ¡¼¤¹âÏßÉϵĹյãÌØÕ÷ +SG_APISHARED_EXPORT void sg_maskData_getLineCornerFeature( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + int maskID, + const SSG_cornerParam cornerPara, //scaleͨ³£È¡bagHµÄ1/4 + std::vector& features); + +//ÌáÈ¡GapÌØÕ÷¡£GapÌØÕ÷£ºÓÉÁ½¸ö¸ºµÄCorner¹¹³ÉµÄÇøÓò +SG_APISHARED_EXPORT void sg_getLineGapFeature( + std::vector& lineData, //ɨÃèÏß + int lineIdx, //µ±Ç°É¨ÃèÏßÐòºÅ + const SSG_cornerParam cornerPara, + const SVzNLRangeD gapParam, + std::vector& line_gaps); + +SG_APISHARED_EXPORT void sg_getLineCornerFeature_BQ( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + double refSteppingZ, + const SSG_cornerParam cornerPara, + std::vector& line_features); + +/// +/// ÌáÈ¡¼¤¹âÏßÉϵĹյãÌØÕ÷£¬µØÃæ¶Ëµã¸½½üµÄ¹ÕµãÊÓΪºÏ¸ñ¹Õµã +/// ¸ù¾ÝSeg½øÐÐcornerÌáÈ¡ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void sg_getLineContourCornerFeature_groundMask_BQ( + std::vector& lineData, + std::vector groundMask, + int lineIdx, + double contourWin, //ground±ßÔµ·¶Î§ + const SSG_cornerParam cornerPara, //scaleͨ³£È¡bagHµÄ1/4 + std::vector& line_features); + +SG_APISHARED_EXPORT void wd_getLineDataIntervals( + std::vector& lineData, + const SSG_lineSegParam lineSegPara, + std::vector& segs); + +// ×îСµã¼¯ÊýÁ¿£¨Ð¡ÓÚ´ËÊýÎÞ·¨ÄâºÏÖ±Ïߣ© +const int MIN_POINT_COUNT = 3; +//ʹÓö˵ãÖ±Ïߣ¬¼ì²éµãµ½Ö±ÏߵľàÀ룬´óÓÚÃÅÏ޵ķָî +SG_APISHARED_EXPORT void split( + SSG_RUN a_run, + std::vector< SVzNL3DPosition>& lineData, + const double maxError, + std::vector< SSG_RUN>& lineSegs); + +/// +/// ÌáÈ¡¼¤¹âÏßÉϵÄÌØÕ÷£ºÌø±ä¡¢µÍÓÚzãÐÖµ¡¢V¼°LÐÍ£¬ÓÃÓÚÁ£¾¶¼ì²â£¨PSM) +/// seg¶Ëµã£ºz¾àÀë´óÓÚÃÅÏÞ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void wd_getLineCornerFeature_PSM( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const double groundZ, + const SSG_cornerParam cornerPara, + SSG_lineFeature* line_features); + +/// ÌáÈ¡¼¤¹âÏßÉϵÄÔ²»·µÄÉϰë¶Î»¡¡£¿í¶ÈÓÉÔ²»·µÄ¿í¶ÈÈ·¶¨ +/// seg¶Ëµã£ºz¾àÀë´óÓÚÃÅÏÞ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void wd_getRingArcFeature( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + const SSG_cornerParam cornerPara, + SVzNLRangeD ringArcWidth, //¶¨×ӵĻ·¿í¶È + std::vector& line_ringArcs //»· +); + +/// +/// ÌáÈ¡¼¤¹âÏßÉϵĹյãÌØÕ÷¡£ÊÇÔÚPSM£¬ LVTypeFeature, BQµÈ¹ÕµãËã·¨µÄ»ù´¡Éϵİ汾¡£ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void wd_getLineCorerFeature( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + const SSG_cornerParam cornerPara, + std::vector& line_cornerFeatures //¹Õµã +); + +/// ÌáÈ¡¼¤¹âÏßÉϵĹյãÌØÕ÷¡£ÊÇÔÚPSM£¬ LVTypeFeature, BQµÈ¹ÕµãËã·¨µÄ»ù´¡Éϵİ汾¡£ +/// ʹÓÃÆ½¾ùµã¾à½øÐмÓËÙ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void wd_getLineCorerFeature_accelerate( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + const SSG_cornerParam cornerPara, + const double pointInterval, + std::vector& segs, + std::vector& line_cornerFeatures //¹ÕµãÌØÕ÷ +); + +//Ìáȡ͹Æð¶Î +SG_APISHARED_EXPORT void wd_getLineRaisedFeature( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + SSG_raisedFeatureParam raisedFeaturePara, //͹Æð²ÎÊý + std::vector& line_raisedFeatures //͹Æð +); + +//Ö±ÏßÌØÕ÷ÌáÈ¡£º¶Ôsplit-and-merge·¨×÷Á˼ò»¯£¬ÒÔÆðµãÖÕµãÖ±Ïß´úÌæÄâºÏÖ±Ïß +SG_APISHARED_EXPORT void wd_surfaceLineSegment( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + SVzNLRangeD lineLenRange, + const SSG_lineSegParam lineSegPara, + std::vector& lineSegs, + std::vector& invlaidLineSegs); + +#if 0 +//¶ÔÒ»¸öÃæµÄ±ßÔµÌØÕ÷½øÐÐÌáÈ¡¡£ +//´ËËã·¨Ê×ÏÈ»ñȡɨÃèÏßÉϸ÷¸ö¶Î£¬È»ºó¶Ô¶ÎµÄ¶Ëµã½øÐд¦Àí£¬µÃµ½±ßÔµÌØÕ÷ +void wd_getSurfaceEdgeFeatures( + std::vector< SVzNL3DPosition>& lineData, + int lineIdx, + const SSG_lineSegParam lineSegPara, + std::vector& edgeFeatures); +#endif + +/// +/// ÌáÈ¡¼¤¹âÏßÉϵÄJumpingÌØÕ÷ +/// nPointIdx±»ÖØÐ¶¨Òå³ÉFeatureÀàÐÍ +/// Ëã·¨Á÷³Ì£º +/// £¨1£©Öðµã¼ÆËãǰÏò½ÇºÍºóÏò½Ç +/// £¨2£©Öðµã¼ÆËã¹Õ½Ç£¬Ë³Ê±ÕëΪ¸º£¬ÄæÊ±ÕëΪÕý +/// £¨3£©ËÑË÷Õý¹Õ½ÇµÄ¼«´óÖµ¡£ +/// £¨4£©ÅжϹսÇÊÇ·ñÎªÌø±ä +/// +SG_APISHARED_EXPORT void sg_getLineJumpFeature_cornerMethod( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const SSG_cornerParam cornerPara, //scaleͨ³£È¡bagHµÄ1/4 + std::vector< SSG_basicFeature1D>& jumpFeatures); + +SG_APISHARED_EXPORT void wd_getLineGloveArcs( + std::vector& lineData, + int lineIdx, + const SSG_gloveArcParam arcPara, + std::vector& gloveArcs); + +/// ÌáÈ¡¼¤¹âÏßÉϵÄÔ²ÖùÐÎÌØÕ÷ +SG_APISHARED_EXPORT void sg_getLineUpperSemiCircleFeature( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const double sieveDiameter, + const SSG_slopeParam slopePara, + std::vector< SSG_featureSemiCircle>& line_features, + cv::Mat& holeMask); + +/// +/// ÌáÈ¡¼¤¹âÏßÉϵļ«Öµµã£¨¼«´óÖµµãºÍ¼«Ð¡Öµµã£© +/// +/// +SG_APISHARED_EXPORT void sg_getLineLocalPeaks( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const double scaleWin, + std::vector< SSG_basicFeature1D>& localMax, + std::vector< SSG_basicFeature1D>& localMin); + +SG_APISHARED_EXPORT void sg_getFlatLineLocalPeaks_vector( + std::vector& lineData, + int lineIdx, + const double scaleWin, + const double minPkHeighth, + const double holeR, + std::vector< SSG_basicFeature1D>& localMax); + +SG_APISHARED_EXPORT void sg_getLineDownJumps( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const double jumpTh, + std::vector< SSG_basicFeature1D>& downJumps); + +//¶Ôfeature½øÐÐÉú³¤ +SG_APISHARED_EXPORT void sg_getFeatureGrowingTrees( + std::vector& lineFeatures, + std::vector& trees, + SSG_treeGrowParam growParam); + +//¶Ôfeature½øÐÐÉú³¤:²»±È½Ïtype£¬Ö»ÅжÏλÖÃÊÇ·ñÏàÁÚ +SG_APISHARED_EXPORT void wd_getFeatureGrowingTrees_noTypeMatch( + std::vector& lineFeatures, + std::vector& feature_trees, + std::vector& ending_trees, + SSG_treeGrowParam growParam); + +//¶Ôsegment feature½øÐÐÉú³¤ +SG_APISHARED_EXPORT void wd_getSegFeatureGrowingTrees( + std::vector>& all_lineFeatures, + std::vector& feature_trees, + SSG_treeGrowParam growParam); + +SG_APISHARED_EXPORT void sg_lineFeaturesGrowing( + int lineIdx, + bool isLastLine, + std::vector& features, + std::vector& trees, + SSG_treeGrowParam growParam); + +//cornerÌØÕ÷Éú³¤ +SG_APISHARED_EXPORT void sg_cornerFeaturesGrowing( + std::vector>& cornerFeatures, + std::vector& trees, + SSG_treeGrowParam growParam); + +//gapÌØÕ÷Éú³¤ +SG_APISHARED_EXPORT void sg_lineGapsGrowing( + int lineIdx, + bool isLastLine, + std::vector& features, + std::vector& trees, + SSG_treeGrowParam growParam); + +//SG_APISHARED_EXPORT void sg_getTreeROI(SSG_featureTree* a_tree); + +//¶Ôending½øÐÐÉú³¤ +SG_APISHARED_EXPORT void sg_getEndingGrowingTrees( + std::vector& lineEndings, + SVzNL3DLaserLine* laser3DPoints, + bool isVScan, + int featureType, + std::vector& trees, + SSG_treeGrowParam growParam); + +//¶Ôending½øÐÐÉú³¤£¬´¹Ö±É¨Ãèʱֻ½øÐÐˮƽÉú³¤£»Ë®Æ½É¨Ãèʱֻ½øÐд¹Ö±Éú³¤ +SG_APISHARED_EXPORT void sg_getEndingGrowingTrees_angleCheck( + std::vector& lineEndings, + SVzNL3DLaserLine* laser3DPoints, + bool isVScan, + int featureType, + std::vector& trees, + SSG_treeGrowParam growParam, + double angleCheckScale); + +//¶ÔɨÃèÏßÉ쵀 +SG_APISHARED_EXPORT void sg_LVFeatureGrowing( + std::vector& lineFeatures, + std::vector& trees, + SSG_bagParam bagParam, + SSG_treeGrowParam growParam, + std::vector& edgePts_0, + std::vector& edgePts_1); + +SG_APISHARED_EXPORT void sg_peakFeatureGrowing( + std::vector>& lineFeatures, + std::vector& trees, + SSG_treeGrowParam growParam); + +//semiCircleÌØÕ÷Éú³¤ +SG_APISHARED_EXPORT void sg_getFeatureGrowingTrees_semiCircle( + std::vector< SSG_featureSemiCircle>& lineFeatures, + const int lineIdx, + const int lineSize, + std::vector& trees, + std::vector& stopTrees, + std::vector& invalidTrees, //±»ÒƳýµÄÊ÷£¬ÕâЩÊ÷¿ÉÄܽ«Ä¿±ê·Ö³É¶à¸öÊ÷£¬´Ó¶ø±»ÒƳý¡£ + SSG_treeGrowParam growParam); + +SSG_meanVar _computeMeanVar(double* data, int size); + +///ËÑË÷¾Ö²¿×î¸ßµã£¨z×îСµã£©¡£ +///ËÑË÷·½·¨£ºÃ¿´Î²½½øËÑË÷´°¿Ú³¤¶ÈµÄÒ»°ë¡£¶Ô¾Ö²¿×î¸ßµã½øÐбê¼Ç£¬·ÀÖ¹±»Öظ´¼Ç¼¡£ +SG_APISHARED_EXPORT void sg_getLocalPeaks( + SVzNL3DLaserLine* scanLines, + int lineNum, + std::vector& peaks, + SSG_localPkParam searchWin); + +/// +/// ÇøÓòÉú³¤·¨£ºÒÔ¾Ö²¿×î¸ßµã×÷ΪÉú³¤ÖÖ×Ó½øÐÐÉú³¤ +/// Éú³¤·½·¨ÓëÒ»°ãµÄÇøÓòÉú³¤²»Í¬£ºÒÔÖÖ×ÓµãΪԲÐÄ×÷Ô²ÖÜɨÃ裬¼Ç¼ɨÃèµ½µÄ±ß½ç +/// +//SG_APISHARED_EXPORT void sg_peakPolarScan(cv::Mat& edgeMask, SVzNL2DPoint a_peak, SSG_polarScanParam polarScanParam, std::vector< SSG_2DValueI>& rgnContour); +//´ÓPeakµã½øÐÐˮƽ´¹Ö±É¨ÃèµÃµ½ÇøÓò±ß½ç +SG_APISHARED_EXPORT void sg_peakXYScan( + SVzNL3DLaserLine* laser3DPoints, + int lineNum, + cv::Mat& featureEdgeMask, + SSG_2DValueI a_peak, + SSG_treeGrowParam growParam, + SSG_bagParam bagParam, + bool rgnPtAsEdge, + std::vector< SSG_lineConotours>& topContour, + std::vector< SSG_lineConotours>& bottomContour, + std::vector< SSG_lineConotours>& leftContour, + std::vector< SSG_lineConotours>& rightContour, + int* maxEdgeId_top, + int* maxEdgeId_btm, + int* maxEdgeId_left, + int* maxEdgeId_right); + +//È¡³öÓë¸ø¶¨edgeIdÏàͬµÄ±ß½çµã +SG_APISHARED_EXPORT void sg_getContourPts( + std::vector< SSG_lineConotours>& contour_all, + int vldEdgeId, + std::vector< SSG_2DValueI>& contourFilter, + int* lowLevelFlag); + +//´Ó±ß½çµã¶ÔÖÐÈ¡³öÓë¸ø¶¨edgeIdÏàͬµÄ±ß½çµã +SG_APISHARED_EXPORT void sg_getPairingContourPts( + std::vector& contourPairs, + std::vector& idPairs, + std::vector< SSG_conotourPair>& contourFilter, + SVzNLRangeD range, + bool isTBDir, + int* lowLevelFlag_0, + int* lowLevelFlag_1); + +//È¡³ö×î¶Ì¾àÀëµÄ±ß½çµã +SG_APISHARED_EXPORT void sg_contourPostProc( + std::vector< SSG_contourPtInfo>& contour, + int maxEdgeIdx, + double sameConturDistTh, + std::vector< SSG_2DValueI>& contourFilter, + int sideID, + int* blockFlag); + +//¾àÀë±ä»» +//input, output¾ùΪfloatÐÍ +SG_APISHARED_EXPORT void sg_distanceTrans(const cv::Mat input, cv::Mat& output, int distType); + +/// +/// ÒÔ5x5·½Ê½Ñ°ÕÒlocalPeaks +/// +/// +/// +SG_APISHARED_EXPORT void sg_getLocalPeaks_distTransform( + cv::Mat& input, + std::vector& peaks, + SSG_localPkParam searchWin); + +/// +/// ʹÓÃÄ£°å·¨Ìáȡֱ½ÇÌØÕ÷ +/// ˮƽÏòÏÂÖ±½ÇÌØÕ÷£º¹Õµã×ó²àdeltaZÔÚÒ»¸öºÜСµÄ·¶Î§ÄÚ£»¹ÕµãÓÒ²àdeltaYÔÚÒ»¸öºÜСµÄ·¶Î§ÄÚ +/// +SG_APISHARED_EXPORT void sg_getLineRigthAngleFeature( + SVzNL3DPosition* lineData, + int dataSize, + int lineIdx, + const SSG_lineRightAngleParam templatePara_HF, + const SSG_lineRightAngleParam templatePara_FH, + const SSG_lineRightAngleParam templatePara_HR, + const SSG_lineRightAngleParam templatePara_RH, + SSG_lineFeature* line_features); + +//¼ÆËãɨÃèROI +SG_APISHARED_EXPORT SVzNL3DRangeD sg_getScanDataROI( + SVzNL3DLaserLine* laser3DPoints, + int lineNum); +//¼ÆËãɨÃèROI: vecotr¸ñʽ +SG_APISHARED_EXPORT SVzNL3DRangeD sg_getScanDataROI_vector( + std::vector< std::vector>& scanLines +); + +//¼ÆËãµãÔÆROI: vecotr¸ñʽ +SG_APISHARED_EXPORT SVzNL3DRangeD wd_getPointCloudROI( + std::vector& scanData); + +//¼ÆËãµãÔÆµÄROIºÍscale: vecotr¸ñʽ +SG_APISHARED_EXPORT SWD_pointCloudPara wd_getPointCloudPara( + std::vector< std::vector>& scanLines); + +//XYÆ½ÃæÖ±ÏßÄâºÏ +SG_APISHARED_EXPORT void lineFitting( + std::vector< SVzNL3DPoint>& inliers, + double* _k, + double* _b); + +//ÄâºÏ³ÉͨÓÃÖ±Ïß·½³Ì£¬°üÀ¨´¹Ö± +SG_APISHARED_EXPORT void lineFitting_abc( + std::vector< SVzNL3DPoint>& inliers, + double* _a, + double* _b, + double* _c); + +/** + * @brief ¿Õ¼äÖ±Ïß×îС¶þ³ËÄâºÏ + * @param points ÊäÈëµÄÈýάµã¼¯£¨ÖÁÉÙ2¸öµã£¬·ñÔòÎÞÒâÒ壩 + * @param center Êä³ö£ºÄâºÏÖ±ÏßµÄÖÊÐÄ£¨»ù×¼µãP0£© + * @param direction Êä³ö£ºÄâºÏÖ±Ïߵķ½ÏòÏòÁ¿v£¨µ¥Î»»¯£© + * @return ÄâºÏÊÇ·ñ³É¹¦£¨µã¼¯ÓÐЧ·µ»Øtrue£© + */ +SG_APISHARED_EXPORT bool fitLine3DLeastSquares( + const std::vector& points, + SVzNL3DPoint& center, + SVzNL3DPoint& direction); + +//Ô²×îС¶þ³ËÄâºÏ +SG_APISHARED_EXPORT double fitCircleByLeastSquare( + const std::vector& pointArray, + SVzNL3DPoint& center, + double& radius); + +//Å×ÎïÏß×îС¶þ³ËÄâºÏ y=ax^2 + bx + c +SG_APISHARED_EXPORT bool leastSquareParabolaFitEigen( + const std::vector& points, + double& a, double& b, double& c, + double& mse, double& max_err); + +//¼ÆËãZ¾ùÖµ +SG_APISHARED_EXPORT double computeMeanZ(std::vector< SVzNL3DPoint>& pts); + +//¼ÆËã½Ç¶È²îÖµ£¬ÔÚ0-180¶È·¶Î§ +SG_APISHARED_EXPORT double computeAngleDiff(double theta1, double theta2); + +//¼ÆËãÖ±Ïß½»µã +SG_APISHARED_EXPORT SVzNL3DPoint computeLineCrossPt_abs( + double a1, double b1, double c1, + double a2, double b2, double c2); + +//¼ÆËã¹ý2µãµÄÖ±Ïß·½³Ì +SG_APISHARED_EXPORT void compute2ptLine( + SVzNL3DPoint pt1, + SVzNL3DPoint pt2, + double* _a, double* _b, double* _c); + +//¼ÆËã¹ý2µãµÄÖ±Ïß·½³Ì,²»Ê¹ÓýṹÌå +SG_APISHARED_EXPORT void compute2ptLine_2( + double x1, double y1, + double x2, double y2, + double* _a, double* _b, double* _c); + +//Ðýת45¶ÈºóµÄÖ±Ïß·½³Ì +SG_APISHARED_EXPORT void rotateLine45Deg( + double _a, double _b, double _c, + double x0, double y0, + double* r_a, double* r_b, double* r_c); + +//¼ÆËãÖ±Ïß½Ç¶È +SG_APISHARED_EXPORT double getLineAngle(const double _a, const double _b, const double _c); + +//¼ÆËãÁ½µãµÄ2D¾àÀë +SG_APISHARED_EXPORT double compute2DLen(SVzNL3DPoint pt1, SVzNL3DPoint pt2); + +//¼ÆËãXYÆ½ÃæÃæµÄÈý½ÇÐζ¥½Ç(p0µÄÕŽÇ) +SG_APISHARED_EXPORT double computeXOYVertexAngle(SVzNL3DPoint p0, SVzNL3DPoint p1, SVzNL3DPoint p2); + +//¼ÆËãµãµ½Ö±Ïß¾àÀë +SG_APISHARED_EXPORT double computePtDistToLine(double x0, double y0, double a, double b, double c); + +//¼ÆËã´¹×ãµã£¬Ö±Ïß·½³Ì£ºy = kx + b +SG_APISHARED_EXPORT SVzNL2DPointD sx_getFootPoint( + double x0, + double y0, + double k, + double b); + +//¼ÆËã´¹×ãµã£¬Ö±Ïß·½³Ì£ºax+by+c = 0 +SG_APISHARED_EXPORT SVzNL2DPointD sx_getFootPoint_abc( + double x0, + double y0, + double A, + double B, + double C); + +//BresenhamËã·¨ +SG_APISHARED_EXPORT void drawLine( + int x0, + int y0, + int x1, + int y1, + std::vector& pts); + +/// +/// Á½²½·¨±ê×¢ +/// +/// Ä¿±êµãΪ¡°1¡±£¬ ¿Õ°×µãΪ¡°0¡± +/// ±ê×¢½á¹û¡£Ã¿¸öµãΪrgnID, ID´Ó2¿ªÊ¼ +/// +SG_APISHARED_EXPORT void SG_TwoPassLabel( + const cv::Mat& bwImg, + cv::Mat& labImg, + std::vector& labelRgns, + int connectivity = 4); + +//¼ÆËãÃæ²ÎÊý: z = Ax + By + C +//res: [0]=A, [1]= B, [2]=-1.0, [3]=C, +SG_APISHARED_EXPORT void vzCaculateLaserPlane( + std::vector Points3ds, + std::vector& res); + +//¼ÆËãÒ»¸öÆ½Ãæµ÷ƽ²ÎÊý¡£ +//Êý¾ÝÊäÈëÖпÉÒÔÓÐÒ»¸öµØÆ½ÃæºÍ²Î¿¼µ÷Æ½Æ½Ãæ£¬ÒÔ×î¸ßµÄÆ½Ãæ½øÐе÷ƽ +//Ðýת¾ØÕóΪµ÷ƽ²ÎÊý£¬¼´½«Æ½Ãæ·¨Ïòµ÷ÕûΪ´¹Ö±ÏòÁ¿µÄ²ÎÊý +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getPlaneCalibPara( + SVzNL3DLaserLine* laser3DPoints, + int lineNum); + +SG_APISHARED_EXPORT SSG_planeCalibPara sg_HCameraVScan_getGroundCalibPara( + std::vector< std::vector>& scanLines); + +//½«Ò»¸öÆ½Ãæµ÷ÕûÎªË®Æ½Æ½Ãæ(zΪ¹Ì¶¨Öµ£©£¬ +SG_APISHARED_EXPORT SSG_planeCalibPara adjustPlaneToXYPlane( + double plane_A, double plane_B, double plane_C //Æ½Ãæ·¨ÏòÁ¿ +); + +//¼ÆËãÒ»¸öÆ½Ãæµ÷ƽ²ÎÊý¡£ +//Êý¾ÝÊäÈëÖпÉÒÔÓÐÒ»¸öµØÆ½ÃæºÍ²Î¿¼µ÷Æ½Æ½Ãæ£¬ÒÔ×î¸ßµÄÆ½Ãæ½øÐе÷ƽ +//Ðýת¾ØÕóΪµ÷ƽ²ÎÊý£¬¼´½«Æ½Ãæ·¨Ïòµ÷ÕûΪ´¹Ö±ÏòÁ¿µÄ²ÎÊý +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getPlaneCalibPara2( + std::vector< std::vector>& scanLines); + +//Õë¶Ô¿×°å¼ÆËãÒ»¸öÆ½Ãæµ÷ƽ²ÎÊý£ºÌáÈ¡²»¾­¹ý¿×µÄɨÃèÏß½øÐÐÆ½ÃæÄâºÏ +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getHolePlaneCalibPara( + std::vector< std::vector>& scanLines); + +//¼ÆËãÒ»¸öÆ½Ãæµ÷ƽ²ÎÊý¡£ +//ÒÔÊý¾ÝÊäÈëÖÐROIÒÔÄÚµÄµã½øÐÐÆ½ÃæÄâºÏ£¬¼ÆËãµ÷ƽ²ÎÊý +//Ðýת¾ØÕóΪµ÷ƽ²ÎÊý£¬¼´½«Æ½Ãæ·¨Ïòµ÷ÕûΪ´¹Ö±ÏòÁ¿µÄ²ÎÊý +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getPlaneCalibPara_ROIs( + SVzNL3DLaserLine* laser3DPoints, + int lineNum, + std::vector& ROIs); + +//¼ÆËãÒ»¸öÆ½Ãæµ÷ƽ²ÎÊý¡£ +//ÒÔÊý¾ÝÊäÈëÖÐROIÒÔÄÚµÄµã½øÐÐÆ½ÃæÄâºÏ£¬¼ÆËãµ÷ƽ²ÎÊý +//Ðýת¾ØÕóΪµ÷ƽ²ÎÊý£¬¼´½«Æ½Ãæ·¨Ïòµ÷ÕûΪ´¹Ö±ÏòÁ¿µÄ²ÎÊý +SG_APISHARED_EXPORT SSG_planeCalibPara sg_getPlaneCalibPara2_ROI( + std::vector< std::vector>& scanLines, + SVzNL3DRangeD roi); + +//¸ù¾ÝÁ½¸öÏòÁ¿¼ÆËãÐýת¾ØÕó +SG_APISHARED_EXPORT SSG_planeCalibPara wd_computeRTMatrix( + SVzNL3DPoint& vector1, + SVzNL3DPoint& vector2); + +// ´ÓÐýת¾ØÕó¼ÆËãÅ·À­½Ç£¨Z-Y-X˳Ðò£© +SG_APISHARED_EXPORT SSG_EulerAngles rotationMatrixToEulerZYX(const double R[3][3]); +// ´ÓÅ·À­½Ç¼ÆËãÐýת¾ØÕó£¨Z-Y-X˳Ðò£© +SG_APISHARED_EXPORT void eulerToRotationMatrixZYX(const SSG_EulerAngles& angles, double R[3][3]); + +//Ïà»ú×Ë̬µ÷ƽ£¬²¢È¥³ýµØÃæ +///camPoseRΪ3x3¾ØÕó +SG_APISHARED_EXPORT void lineDataRT( + SVzNL3DLaserLine* a_line, + const double* camPoseR, + double groundH); +SG_APISHARED_EXPORT void lineDataRT_vector( + std::vector< SVzNL3DPosition>& a_line, + const double* camPoseR, + double groundH); +SG_APISHARED_EXPORT void HCamera_lineDataRT_vector( + std::vector< SVzNL3DPosition>& a_line, + const double* camPoseR, + double groundH); +SG_APISHARED_EXPORT void lineDataRT_RGBD( + SVzNLXYZRGBDLaserLine* a_line, + const double* camPoseR, + double groundH); + +//»ùÓÚÏàÁÚµãµÄ¾ÛÀà +SG_APISHARED_EXPORT void sg_pointClustering( + std::vector< SVzNL3DPosition>& pts, + double clusterDist, + std::vector>& objClusters //result +); + +//»ùÓÚÕ¤¸ñÉϵãµÄ´°¿ÚÄÚµÄÏàÁÚµãµÄ¾ÛÀ࣬¾ÛÀàÌõ¼þÓÉ3DµãµÄÁÚÓò¾ö¶¨ +//ʹÓÃvector¹¹³É2ά½á¹¹ÌåÊý×é +SG_APISHARED_EXPORT void wd_gridPointClustering( + std::vector>& featureMask, + std::vector>& feature3DInfo, + int clusterCheckWin, //ËÑË÷´°¿Ú + SSG_treeGrowParam growParam,//¾ÛÀàÌõ¼þ + int clusterID, //µ±Ç°ClusterµÄID + std::vector< SVzNL2DPoint>& a_cluster, //result + SVzNL3DRangeD& clusterRoi //roi3D +); + +//¶ÔɨÃèÊý¾ÝµÄ¾ÛÀà +SG_APISHARED_EXPORT void wd_gridPointClustering_2( + std::vector>& gridData, + std::vector>& pointMaskInfo, //·ÀÖ¹¾ÛÀàÊ±ÖØ¸´Ñ¡ÖÐ + int clusterCheckWin, //ËÑË÷´°¿Ú + SSG_treeGrowParam growParam,//¾ÛÀàÌõ¼þ + int clusterID, //µ±Ç°ClusterµÄID + std::vector< SVzNL2DPoint>& a_cluster, //result + SVzNL3DRangeD& clusterRoi //roi3D +); + +//ʹÓþÛÀà·½·¨Íê³É8Á¬Í¨Á¬Í¨Óò·ÖÎö +SG_APISHARED_EXPORT void wd_gridPointClustering_labelling( + std::vector>& featureMask, + std::vector>& feature3DInfo, + int clusterID, //µ±Ç°ClusterµÄID + std::vector< SVzNL2DPoint>& a_cluster, //result + SVzNLRect& clusterRoi //roi2D +); + +//¶ÔÕ¤¸ñ»¯Êý¾Ý½øÐÐXYÆ½ÃæÉϵÄͶӰÁ¿»¯£¬²¢¶ÔÁ¿»¯²úÉúµÄ¿Õ°×µã½øÐвåÖµ +SG_APISHARED_EXPORT void pointClout2DProjection( + std::vector< std::vector>& gridScanData, + SVzNLRangeD x_range, + SVzNLRangeD y_range, + double scale, + double cuttingGrndZ, + int edgeSkip, + double inerPolateDistTh, //²åÖµãÐÖµ¡£´óÓÚ´ËãÐÖµµÄ²»½øÐÐÁ¿»¯²åÖµ + cv::Mat& projectionData,//ͶӰÁ¿»¯Êý¾Ý£¬³õʼ»¯ÎªÒ»¸ö¼«´óÖµ1e+6 + cv::Mat& backIndexing //±ê¼Ç×ø±êË÷Òý£¬ÓÃÓÚ»ØÕÒ3D×ø±ê +); + +//¶ÔÕ¤¸ñ»¯Êý¾Ý½øÐÐXYÆ½ÃæÉϵÄͶӰÁ¿»¯£¬ZÖµ±£Áô£¬²¢¶ÔÁ¿»¯²úÉúµÄ¿Õ°×µã½øÐвåÖµ +SG_APISHARED_EXPORT void pointClout2DQuantization( + std::vector< std::vector>& gridScanData, + SVzNLRangeD x_range, + SVzNLRangeD y_range, + double scale, + double cuttingGrndZ, + int edgeSkip, + double inerPolateDistTh, //²åÖµãÐÖµ¡£´óÓÚ´ËãÐÖµµÄ²»½øÐÐÁ¿»¯²åÖµ + std::vector> quantiData, //Á¿»¯Êý¾Ý£¬³õʼ»¯ÎªÒ»¸ö¼«´óÖµ1e+6 + std::vector> backIndexing //±ê¼Ç×ø±êË÷Òý£¬ÓÃÓÚ»ØÕÒ3D×ø±ê +); + +//·ÖË®ÁëËã·¨ +SG_APISHARED_EXPORT void watershed(SWD_waterShedImage& img); +// ¸ù¾ÝÊäÈëµÄÖÖ×Óµã½øÐзÖË®ÁëËã·¨ +SG_APISHARED_EXPORT void wd_seedWatershed( + SWD_waterShedImage& img, + std::vector& watershedSeeds, //ÖÖ×Óµã + int maxLevel, //×î´óˮλ + int startMakerID //ÆðʼMarkerµÄID +); + +//µãÔÆÂ˲¨Ô¤´¦Àí +SG_APISHARED_EXPORT void wd_noiseFilter( + std::vector< std::vector>& scanLines, + const SSG_outlierFilterParam filterParam, + int* errCode); + +// Eigen¿âʵÏÖ£º¼ÆËã´Ópts1Ïòpts2µÄÐý×ªÆ½ÒÆ¾ØÕó +//ÐèÒª +SG_APISHARED_EXPORT void caculateRT( + const std::vector& pts1, + const std::vector& pts2, + cv::Mat& R, cv::Mat& T, + cv::Point3d& C1, cv::Point3d& C2); + +//¼ÆËãµãÐý×ªÆ½ÒÆºóµÄλÖà +SG_APISHARED_EXPORT void pointRT(const cv::Mat& R, const cv::Mat& T, + const cv::Point3d& originPt, const cv::Point3d& rtOriginPT, //RT(Ðý×ªÆ½ÒÆ£©Ç°ºóµÄÖÊÐÄ + const cv::Point3d& pt, cv::Point3d& rtPt); //RTǰºóµÄµã + +//¼ÆËãµãÐý×ªÆ½ÒÆºóµÄλÖà +SG_APISHARED_EXPORT void pointRT_2(const cv::Mat& R, const cv::Mat& T, + const cv::Point3d& pt, cv::Point3d& rtPt); //RTǰºóµÄµã + +SG_APISHARED_EXPORT void pointRotate(const cv::Mat& R, + const cv::Point3d& pt, cv::Point3d& rtPt); //RotateǰºóµÄµã + +//´ÓÅ·À­½Ç¼ÆËãÐýת¾ØÕó +SG_APISHARED_EXPORT void WD_EulerRpyToRotation(double rpy[3], double matrix3d[9]); + +//´ÓÅ·À­½Ç¼ÆËã·½ÏòʸÁ¿ +SG_APISHARED_EXPORT void WD_EulerRpyToDirVectors(double rpy[3], std::vector& dirVectors); diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.dll index 06478396..6dc95dcb 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.lib b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.lib index a48f72bd..0149c7d7 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.lib and b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.lib differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Debug/baseAlgorithm.pdb index 3d4765b1..1ead6b9c 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 8c6f8cee..911d5806 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 45c47cb2..0694f509 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 67231993..eb0cd44c 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.lib b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.lib index f26642ed..2b5745a1 100644 Binary files a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.lib and b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.lib differ diff --git a/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb b/AppAlgo/workpieceHolePositioning/Windows/x64/Release/baseAlgorithm.pdb index 099c832e..4ddaf57e 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 df5eb94a..2ed1c3e7 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 f18c28cf..000ad049 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 a1c4e848..8b503d4d 100644 --- a/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp +++ b/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp @@ -12,6 +12,7 @@ #include #include #include +#include "SG_baseAlgo_Export.h" typedef struct { @@ -153,6 +154,12 @@ void _outputWorkpieceInfo(char* fileName, std::vector< WD_workpieceInfo>& workpi } sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpiecePositioning[i].center.x, workpiecePositioning[i].center.y, workpiecePositioning[i].center.z); sw << dataStr << std::endl; + sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", workpiecePositioning[i].x_dir.x, workpiecePositioning[i].x_dir.y, workpiecePositioning[i].x_dir.z); + sw << dataStr << std::endl; + sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", workpiecePositioning[i].y_dir.x, workpiecePositioning[i].y_dir.y, workpiecePositioning[i].y_dir.z); + sw << dataStr << std::endl; + sprintf_s(dataStr, 50, " z_dir: (%g, %g, %g)", workpiecePositioning[i].z_dir.x, workpiecePositioning[i].z_dir.y, workpiecePositioning[i].z_dir.z); + sw << dataStr << std::endl; } sw.close(); } @@ -368,20 +375,27 @@ void _outputRGBDResult_RGBD( size = 2; for (int i = 0; i < objNumber; i++) { + SVzNL3DPoint dirPt; + dirPt = { workpiecePositioning[i].center.x + workpiecePositioning[i].y_dir.x * 10, + workpiecePositioning[i].center.y + workpiecePositioning[i].y_dir.y * 10, + workpiecePositioning[i].center.z + workpiecePositioning[i].y_dir.z * 10 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << workpiecePositioning[i].center.x << "," << workpiecePositioning[i].center.y << "," << workpiecePositioning[i].center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; - sw << "{" << workpiecePositioning[i].y_dir.x << "," << workpiecePositioning[i].y_dir.y << "," << workpiecePositioning[i].y_dir.z << "}-"; + sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; + dirPt = { workpiecePositioning[i].center.x + workpiecePositioning[i].z_dir.x * 10, + workpiecePositioning[i].center.y + workpiecePositioning[i].z_dir.y * 10, + workpiecePositioning[i].center.z + workpiecePositioning[i].z_dir.z * 10 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << workpiecePositioning[i].center.x << "," << workpiecePositioning[i].center.y << "," << workpiecePositioning[i].center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; - sw << "{" << workpiecePositioning[i].z_dir.x << "," << workpiecePositioning[i].z_dir.y << "," << workpiecePositioning[i].z_dir.z << "}-"; + sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; lineIdx++; @@ -398,15 +412,17 @@ void _outputRGBDResult_RGBD( lineIdx++; } } + SVzNL3DPoint dirPt = { workpiecePositioning[0].center.x + workpiecePositioning[0].y_dir.x * 10, + workpiecePositioning[0].center.y + workpiecePositioning[0].y_dir.y * 10, + workpiecePositioning[0].center.z + workpiecePositioning[0].y_dir.z * 10 }; sw << "Poly_" << lineIdx << "_2" << std::endl; sw << "{" << workpiecePositioning[0].center.x << "," << workpiecePositioning[0].center.y << "," << workpiecePositioning[0].center.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; - sw << "{" << workpiecePositioning[0].y_dir.x << "," << workpiecePositioning[0].y_dir.y << "," << workpiecePositioning[0].y_dir.z << "}-"; + sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-"; sw << "{0,0}-{0,0}-"; sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl; - sw.close(); } @@ -423,7 +439,8 @@ SVzNL3DPoint _pointRT(SVzNL3DPoint& origin, const double* R, const double* T) } #define TEST_COMPUTE_CALIB_PARA 0 -#define TEST_COMPUTE_HOLE 1 +#define TEST_COMPUTE_HOLE 0 +#define TEST_COMPUTE_RT 1 #define TEST_GROUP 1 int main() { @@ -433,15 +450,107 @@ int main() }; SVzNLRange fileIdx[TEST_GROUP] = { - {1,4}, + {6,6}, }; const char* ver = wd_workpieceHolePositioningVersion(); printf("ver:%s\n", ver); +#if TEST_COMPUTE_RT + std::vector pts_eye; + pts_eye.resize(6); + std::vector pts_robot; + pts_robot.resize(6); + pts_eye[0] = { 187.22, -99.43, 1797.70 }; //, R = 0.6413, P = 0.0302, Y = -91.1494 + pts_eye[1] = { 186.50, -140.52, 1797.69 }; // R = 0.6413, P = 0.0302, Y = -88.8130 + pts_eye[2] = { 256.73, -93.55, 1797.83 }; //, R = 0.6413, P = 0.0302, Y = -89.3432 + pts_eye[3] = { 236.69, -48.82, 1797.77 }; // R = 0.6413, P = 0.0302, Y = -89.5285 + pts_eye[4] = { 173.62, 13.92, 1797.30 };// R = 0.6413, P = 0.0302, Y = -89.6450 + pts_eye[5] = { 232.11, -153.38, 1797.88 };// R = 0.6413, P = 0.0302, Y = -82.0278 + + //A:绕z, B:绕y, C:绕x + pts_robot[0] = { 55.830, -984.472, 97.687 }; // A:0.018 B : -0.638 C : -0.292 + pts_robot[1] = { 95.469, -985.345, 97.782 }; // A:-1.032 B : -0.354 C : 1.001 + pts_robot[2] = { 47.908, -1053.709, 97.802 }; // A:-1.032 B : -0.356 C : 0.998 + pts_robot[3] = { 3.646, -1033.152, 96.494 }; // A:-1.028 B : -0.367 C : 0.442 + pts_robot[4] = { -58.843, -969.793, 95.297 }; // A:-1.029 B : -0.367 C : 0.442 + pts_robot[5] = { 108.031, -1029.803, 98.333 }; // A:-9.208 B : -0.367 C : 0.442 + + //使用å‰�6组数æ�® + std::vector test_pts_eye; + std::vector test_pts_robot; + for (int i = 0; i < 5; i++) + { + test_pts_eye.push_back(pts_eye[i]); + test_pts_robot.push_back(pts_robot[i]); + } + //对空间两组对应点计算旋转平移矩阵 + // Eigen库实现 + cv::Mat R, T; + cv::Point3d C_eye, C_robot; + caculateRT( + test_pts_eye, + test_pts_robot, + R, T, + C_eye, C_robot); + + std::cout << "æ–¹å�‘å�‘é‡�转æ�¢ç»“果:" << std::endl; + std::cout << std::fixed << std::setprecision(6); // 固定å°�æ•°ä½�数为6 + std::cout << R << std::endl; + std::cout << T << std::endl; + + //验算6è½´å§¿æ€� + std::vector verify_pts_eye; + verify_pts_eye.insert(verify_pts_eye.end(), pts_eye.begin(), pts_eye.end()); + cv::Point3d a_center = { 232.997, -173.533, 1795.9 }; + verify_pts_eye.push_back(a_center); + std::vector> pose_eye; + pose_eye.resize(7); + for (int i = 0; i < 7; i++) + pose_eye[i].resize(3); + pose_eye[0][0] = { -0.020, -1.000, -0.011 }; pose_eye[0][1] = { 1.000, -0.020, -0.001 }; pose_eye[0][2] = { 0.001, -0.011, 1.000 }; + pose_eye[1][0] = { 0.021,-1.000,-0.011 }; pose_eye[1][1] = { 1.000,0.021,-0.000 }; pose_eye[1][2] = { 0.001,-0.011,1.000 }; + pose_eye[2][0] = { 0.011,-1.000,-0.011 }; pose_eye[2][1] = { 1.000,0.011,-0.000 }; pose_eye[2][2] = { 0.001,-0.011,1.000 }; + pose_eye[3][0] = { 0.008,-1.000,-0.011 }; pose_eye[3][1] = { 1.000,0.008,-0.000 }; pose_eye[3][2] = { 0.001,-0.011,1.000 }; + pose_eye[4][0] = { 0.006,-1.000,-0.011 }; pose_eye[4][1] = { 1.000,0.006,-0.000 }; pose_eye[4][2] = { 0.001,-0.011,1.000 }; + pose_eye[5][0] = { 0.139,-0.990,-0.011 }; pose_eye[5][1] = { 0.990,0.139,0.001 }; pose_eye[5][2] = { 0.001,-0.011,1.000 }; + pose_eye[6][0] = { 0.136746, -0.990563, -0.00926168 }; pose_eye[6][1] = { 0.990606, 0.136747, 0.000517805 }; pose_eye[6][2] = { 0.000753588, -0.00924548, 0.999957 }; + for (int i = 0; i < 7; i++) + { + cv::Point3d rtPt; + pointRT_2(R, T, verify_pts_eye[i], rtPt); //RTå‰�å�Žçš„点 + + std::vector dirVectors_eye = pose_eye[i]; + //dirVectors_eye[0] = { -dirVectors_eye[0].x, -dirVectors_eye[0].y, -dirVectors_eye[0].z }; + dirVectors_eye[1] = { -dirVectors_eye[1].x, -dirVectors_eye[1].y, -dirVectors_eye[1].z }; + dirVectors_eye[2] = { -dirVectors_eye[2].x, -dirVectors_eye[2].y, -dirVectors_eye[2].z }; + std::vector dirVectors_robot; + for (int j = 0; j < 3; j++) + { + cv::Point3d rt_pt; + pointRotate(R, dirVectors_eye[j], rt_pt); + dirVectors_robot.push_back(rt_pt); + } + //生æˆ�旋转矩阵 + double R_pose[3][3]; + R_pose[0][0] = dirVectors_robot[0].x; + R_pose[0][1] = dirVectors_robot[1].x; + R_pose[0][2] = dirVectors_robot[2].x; + R_pose[1][0] = dirVectors_robot[0].y; + R_pose[1][1] = dirVectors_robot[1].y; + R_pose[1][2] = dirVectors_robot[2].y; + R_pose[2][0] = dirVectors_robot[0].z; + R_pose[2][1] = dirVectors_robot[1].z; + R_pose[2][2] = dirVectors_robot[2].z; + SSG_EulerAngles test_rpy = rotationMatrixToEulerZYX(R_pose); + std::cout << i << ":" << std::endl; + std::cout << rtPt.x << "," << rtPt.y << "," << rtPt.z << std::endl; + std::cout << test_rpy.roll << "," << test_rpy.pitch << "," << test_rpy.yaw << std::endl; + } +#endif #if TEST_COMPUTE_CALIB_PARA char _calib_datafile[256]; - sprintf_s(_calib_datafile, "%sLaserData_ground.txt", dataPath[0]); + sprintf_s(_calib_datafile, "%sLaserData_ground2.txt", dataPath[0]); int lineNum = 0; float lineV = 0.0f; int dataCalib = 0; @@ -471,7 +580,7 @@ int main() sprintf_s(_out_file, "%sscanData_ground_calib_verify.txt", dataPath[0]); int headNullLines = 0; _outputScanDataFile_vector(_out_file, scanData, false, &headNullLines); - +#if 0 for (int fidx = fileIdx[0].nMin; fidx <= fileIdx[0].nMax; fidx++) { //fidx =4; @@ -491,6 +600,7 @@ int main() int headNullLines = 0; _outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines); } +#endif printf("%s: calib done!\n", _calib_datafile); } #endif