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