algoLib/hybridPosePositioning_test/hybridPosePositioning_test.cpp
jerryzeng a6f1514273 hybridPosePositioning
version 1.4.1 : 转子钢芯, 每个输出结果添加了2D图像坐标
2026-09-18 17:23:42 +08:00

2883 lines
94 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <VZNL_Types.h>
#include "direct.h"
#include <string>
#include "hybridPosePositioning_Export.h"
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <limits>
#include "SG_baseAlgo_Export.h"
typedef struct
{
int r;
int g;
int b;
}SG_color;
typedef struct
{
int nPointIdx;
double x;
double y;
double z;
float r;
float g;
float b;
} SPointXYZRGB;
SVzNL3DPoint _ptRotate(SVzNL3DPoint pt3D, double matrix3d[9])
{
SVzNL3DPoint _r_pt;
_r_pt.x = pt3D.x * matrix3d[0] + pt3D.y * matrix3d[1] + pt3D.z * matrix3d[2];
_r_pt.y = pt3D.x * matrix3d[3] + pt3D.y * matrix3d[4] + pt3D.z * matrix3d[5];
_r_pt.z = pt3D.x * matrix3d[6] + pt3D.y * matrix3d[7] + pt3D.z * matrix3d[8];
return _r_pt;
}
SSG_planeCalibPara _readCalibPara(char* fileName)
{
//设置初始结果
double initCalib[9] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0 };
SSG_planeCalibPara planePara;
for (int i = 0; i < 9; i++)
planePara.planeCalib[i] = initCalib[i];
planePara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
planePara.invRMatrix[i] = initCalib[i];
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return planePara;
//调平矩阵
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[0], &planePara.planeCalib[1], &planePara.planeCalib[2]);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[3], &planePara.planeCalib[4], &planePara.planeCalib[5]);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.planeCalib[6], &planePara.planeCalib[7], &planePara.planeCalib[8]);
//地面高度
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf", &planePara.planeHeight);
//反向旋转矩阵
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[0], &planePara.invRMatrix[1], &planePara.invRMatrix[2]);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[3], &planePara.invRMatrix[4], &planePara.invRMatrix[5]);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), "%lf, %lf, %lf", &planePara.invRMatrix[6], &planePara.invRMatrix[7], &planePara.invRMatrix[8]);
inputFile.close();
return planePara;
}
void _outputCalibPara(char* fileName, SSG_planeCalibPara calibPara)
{
std::ofstream sw(fileName);
char dataStr[250];
//调平矩阵
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[0], calibPara.planeCalib[1], calibPara.planeCalib[2]);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[3], calibPara.planeCalib[4], calibPara.planeCalib[5]);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.planeCalib[6], calibPara.planeCalib[7], calibPara.planeCalib[8]);
sw << dataStr << std::endl;
//地面高度
sprintf_s(dataStr, 250, "%g", calibPara.planeHeight);
sw << dataStr << std::endl;
//反向旋转矩阵
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[0], calibPara.invRMatrix[1], calibPara.invRMatrix[2]);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[3], calibPara.invRMatrix[4], calibPara.invRMatrix[5]);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, "%g, %g, %g", calibPara.invRMatrix[6], calibPara.invRMatrix[7], calibPara.invRMatrix[8]);
sw << dataStr << std::endl;
sw.close();
}
//读取3D和2D数据
void vzReadLaserScanPointFromFile_XYZUV_vector(const char* fileName, std::vector<std::vector< SVzNLPositionD>>& scanData)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return;
std::vector< SVzNLPositionD> a_line;
int ptIdx = 0;
while (getline(inputFile, linedata))
{
if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int ptSize = (int)a_line.size();
if (ptSize > 0)
{
scanData.push_back(a_line);
}
a_line.clear();
ptIdx = 0;
}
else if (0 == strncmp("{", linedata.c_str(), 1))
{
float X, Y, Z;
float leftU, leftV;
float rightU, rightV;
sscanf_s(linedata.c_str(), "{ %f, %f, %f }-{ %f, %f }-{ %f, %f }", &X, &Y, &Z, &leftU, &leftV, &rightU, &rightV);
if (Z > 1e-4)
int kkk = 1;
SVzNLPositionD a_pt;
a_pt.ptLeft2D.x = leftU;
a_pt.ptLeft2D.y = leftV;
a_pt.ptRight2D.x = rightU;
a_pt.ptRight2D.y = rightV;
a_pt.pt3D.x = X;
a_pt.pt3D.y = Y;
a_pt.pt3D.z = Z;
a_pt.nPointIdx = ptIdx;
ptIdx++;
a_line.push_back(a_pt);
}
}
//last line
int ptSize = (int)a_line.size();
if (ptSize > 0)
{
scanData.push_back(a_line);
a_line.clear();
}
inputFile.close();
return;
}
void vzReadLaserScanPointFromFile_XYZ_vector(const char* fileName, std::vector<std::vector< SVzNL3DPosition>>& scanData)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return;
std::vector< SVzNL3DPosition> a_line;
int ptIdx = 0;
while (getline(inputFile, linedata))
{
if (0 == strncmp("Line_", linedata.c_str(), 5))
{
int ptSize = (int)a_line.size();
if (ptSize > 0)
{
scanData.push_back(a_line);
}
a_line.clear();
ptIdx = 0;
}
else if (0 == strncmp("{", linedata.c_str(), 1))
{
float X, Y, Z;
int imageY = 0;
float leftX, leftY;
float rightX, rightY;
sscanf_s(linedata.c_str(), "{%f,%f,%f}-{%f,%f}-{%f,%f}", &X, &Y, &Z, &leftX, &leftY, &rightX, &rightY);
SVzNL3DPosition a_pt;
a_pt.pt3D.x = X;
a_pt.pt3D.y = Y;
a_pt.pt3D.z = Z;
a_pt.nPointIdx = ptIdx;
ptIdx++;
a_line.push_back(a_pt);
}
}
//last line
int ptSize = (int)a_line.size();
if (ptSize > 0)
{
scanData.push_back(a_line);
a_line.clear();
}
inputFile.close();
return;
}
int counterLinePtNum_XYZ(std::vector< SVzNL3DPosition>& lineData)
{
int num = 0;
for (int i = 0; i < (int)lineData.size(); i++)
{
if (lineData[i].pt3D.z > 1e-4)
num++;
}
return num;
}
int counterLinePtNum_XYZUV(std::vector< SVzNLPositionD>& lineData)
{
int num = 0;
for (int i = 0; i < (int)lineData.size(); i++)
{
if (lineData[i].pt3D.z > 1e-4)
num++;
}
return num;
}
void _removeZeroLines_XYZ(std::vector<std::vector< SVzNL3DPosition>>& scanData)
{
int lineNum = (int)scanData.size();
int firstLine = -1;
int lastLine = 0;
for (int line = 0; line < lineNum; line++)
{
int num = counterLinePtNum_XYZ(scanData[line]);
if ((num > 0) && (firstLine < 0))
firstLine = line;
if (num > 0)
lastLine = line;
}
if (firstLine < 0)
{
scanData.clear();
return;
}
if ((lastLine < (lineNum - 1)) && (lastLine > 0))
scanData.erase(scanData.begin() + lastLine + 1, scanData.end());
scanData.erase(scanData.begin(), scanData.begin() + firstLine);
return;
}
void _removeZeroLines_XYZUV(std::vector<std::vector< SVzNLPositionD>>& scanData)
{
int lineNum = (int)scanData.size();
int firstLine = -1;
int lastLine = 0;
for (int line = 0; line < lineNum; line++)
{
int num = counterLinePtNum_XYZUV(scanData[line]);
if ((num > 0) && (firstLine < 0))
firstLine = line;
if (num > 0)
lastLine = line;
}
if (firstLine < 0)
{
scanData.clear();
return;
}
if ((lastLine < (lineNum - 1)) && (lastLine > 0))
scanData.erase(scanData.begin() + lastLine + 1, scanData.end());
scanData.erase(scanData.begin(), scanData.begin() + firstLine);
return;
}
void vzReadObj2DROI_1(const char* fileName, std::vector<WD_objArea2D>& objROIs)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return;
while (getline(inputFile, linedata))
{
if (0 == strncmp("obj_", linedata.c_str(), 4))
{
int objID;
char type;
float L, T, W, H, score;
sscanf_s(linedata.c_str(), "obj_%d: C=%c, Rect={ %f, %f, %f, %f }, Score=%f",
&objID, &type, sizeof(type), &L, &T, &W, &H, &score);
WD_objArea2D a_roi;
if ('a' == type)
a_roi.workpieceType = 1;
else if ('b' == type)
a_roi.workpieceType = 2;
else if ('c' == type)
a_roi.workpieceType = 3;
a_roi.roi.left = L;
a_roi.roi.top = T;
a_roi.roi.right = L + W;
a_roi.roi.bottom = T + H;
a_roi.score2D = score;
objROIs.push_back(a_roi);
}
}
inputFile.close();
return;
}
void vzReadObj2DROI(const char* fileName, std::vector<WD_objArea2D>& objROIs)
{
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return;
while (getline(inputFile, linedata))
{
if (0 == strncmp("obj_", linedata.c_str(), 4))
{
int objID;
char type;
float Cx, Cy, R, score;
sscanf_s(linedata.c_str(), "obj_%d: C=%c, { %f, %f }, R=%f, Score=%f",
&objID, &type, sizeof(type), &Cx, &Cy, &R, &score);
WD_objArea2D a_roi;
if ('a' == type)
a_roi.workpieceType = 1;
else if ('b' == type)
a_roi.workpieceType = 2;
else if ('c' == type)
a_roi.workpieceType = 3;
a_roi.roi.left = Cx - R ;
a_roi.roi.top = Cy - R;
a_roi.roi.right = Cx + R;
a_roi.roi.bottom = Cy + R;
a_roi.score2D = score;
objROIs.push_back(a_roi);
}
}
inputFile.close();
return;
}
void _outputRGBDResult_XYZUV_RGBD(
char* fileName,
std::vector<std::vector<SVzNLPositionD>>& scanLines,
std::vector< WD_workpieceInfo>& workpiecePositions)
{
std::vector<SVzNL3DPosition> objects;
int objNumber = (int)workpiecePositions.size();
for (int i = 0; i < objNumber; i++)
{
SVzNL3DPosition a_objPt;
a_objPt.pt3D = workpiecePositions[i].center;
objects.push_back(a_objPt);
}
int lineNum = (int)scanLines.size();
std::ofstream sw(fileName);
int realLines = (objNumber == 0) ? lineNum : (lineNum + 1);
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int maxLineIndex = 0;
int max_stamp = 0;
SG_color rgb = { 0, 0, 0 };
SG_color objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
int lineIdx = 0;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
for (int i = 0; i < linePtNum; i++)
{
SVzNLPositionD* pt3D = &scanLines[line][i];
if (pt3D->nPointIdx > 0)
int kkk = 1;
int flag = pt3D->nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 1;
}
else
{
rgb = { 200, 200, 200 };
size = 1;
}
float x = (float)pt3D->pt3D.x;
float y = (float)pt3D->pt3D.y;
float z = (float)pt3D->pt3D.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
int linePtNum = (int)objects.size();
sw << "Line_" << lineNum << "_0_" << linePtNum + 1 << std::endl;
lineNum++;
for (int i = 0; i < linePtNum; i++)
{
if (i == 0)
{
size = 10;
rgb = { 255, 0, 0 };
}
else
{
rgb = { 255, 255, 0 };
size = 10;
}
//int colorIdx = objects[i].nPointIdx % 8;
//rgb = objColor[colorIdx];
float x = (float)objects[i].pt3D.x;
float y = (float)objects[i].pt3D.y;
float z = (float)objects[i].pt3D.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
//输出方向线条
rgb = { 255, 0, 0 };
size = 2;
for (int i = 0; i < objNumber; i++)
{
if (abs(workpiecePositions[i].y_dir.z) > 1e-4)
{
SVzNL3DPoint dirPt;
dirPt = { workpiecePositions[i].center.x + workpiecePositions[i].y_dir.x * 10,
workpiecePositions[i].center.y + workpiecePositions[i].y_dir.y * 10,
workpiecePositions[i].center.z + workpiecePositions[i].y_dir.z * 10 };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << workpiecePositions[i].center.x << "," << workpiecePositions[i].center.y << "," << workpiecePositions[i].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
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 = { workpiecePositions[i].center.x + workpiecePositions[i].z_dir.x * 10,
workpiecePositions[i].center.y + workpiecePositions[i].z_dir.y * 10,
workpiecePositions[i].center.z + workpiecePositions[i].z_dir.z * 10 };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << workpiecePositions[i].center.x << "," << workpiecePositions[i].center.y << "," << workpiecePositions[i].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
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++;
}
}
sw.close();
}
void _outputRGBDResult_XYZ_RGBD_binInfo(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
WD_HRM_BinInfo& poseInfo)
{
int objNumber = 0;
if (poseInfo.center.z > 1e-4)
objNumber = 1;
int lineNum = (int)scanLines.size();
std::ofstream sw(fileName);
int realLines = (objNumber == 0) ? lineNum : (lineNum + 1);
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int maxLineIndex = 0;
int max_stamp = 0;
SG_color rgb = { 0, 0, 0 };
SG_color objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
int lineIdx = 0;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
for (int i = 0; i < linePtNum; i++)
{
SVzNL3DPosition* pt3D = &scanLines[line][i];
if (pt3D->nPointIdx > 0)
int kkk = 1;
int flag = pt3D->nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 5;
}
else
{
rgb = { 200, 200, 200 };
size = 1;
}
float x = (float)pt3D->pt3D.x;
float y = (float)pt3D->pt3D.y;
float z = (float)pt3D->pt3D.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
if (poseInfo.center.z > 1e-4)
{
sw << "Line_" << lineNum << "_0_1" << std::endl;
lineNum++;
size = 20;
rgb = { 255, 255, 0 };
float x = (float)poseInfo.center.x;
float y = (float)poseInfo.center.y;
float z = (float)poseInfo.center.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
//输出方向线条
rgb = { 250, 0, 0 };
size = 2;
double dirLen = 500;
SVzNL3DPoint dirPt1 = { poseInfo.center.x + poseInfo.x_dir.x * dirLen,
poseInfo.center.y + poseInfo.x_dir.y * dirLen,
poseInfo.center.z + poseInfo.x_dir.z * dirLen };
SVzNL3DPoint dirPt2 = { poseInfo.center.x - poseInfo.x_dir.x * dirLen,
poseInfo.center.y - poseInfo.x_dir.y * dirLen,
poseInfo.center.z - poseInfo.x_dir.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
SVzNL3DPoint pose_y = poseInfo.y_dir;
rgb = { 0, 250, 0 };
SVzNL3DPoint dirPt;
dirPt = { poseInfo.center.x + pose_y.x * dirLen,
poseInfo.center.y + pose_y.y * dirLen,
poseInfo.center.z + pose_y.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << poseInfo.center.x << "," << poseInfo.center.y << "," << poseInfo.center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
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++;
rgb = { 0, 0, 250 };
dirPt1 = { poseInfo.center.x + poseInfo.bottomNormal.x * dirLen,
poseInfo.center.y + poseInfo.bottomNormal.y * dirLen,
poseInfo.center.z + poseInfo.bottomNormal.z * dirLen };
dirPt2 = { poseInfo.center.x - poseInfo.bottomNormal.x * dirLen,
poseInfo.center.y - poseInfo.bottomNormal.y * dirLen,
poseInfo.center.z - poseInfo.bottomNormal.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
//输出外接矩形
dirPt1 = poseInfo.minRectVertex[0];
dirPt2 = poseInfo.minRectVertex[1];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = poseInfo.minRectVertex[1];
dirPt2 = poseInfo.minRectVertex[2];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = poseInfo.minRectVertex[2];
dirPt2 = poseInfo.minRectVertex[3];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = poseInfo.minRectVertex[3];
dirPt2 = poseInfo.minRectVertex[0];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
sw.close();
}
void _outputRGBDResult_XYZ_RGBD_workpieceInfo(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
std::vector<WD_workpieceInfo>& poseInfo,
WD_HRM_BinInfo* binInfo,
double dirLen)
{
int objNumber = 0;
if (poseInfo.size()>0)
objNumber = 1;
int lineNum = (int)scanLines.size();
std::ofstream sw(fileName);
int realLines = (objNumber == 0) ? lineNum : (lineNum + 1);
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int maxLineIndex = 0;
int max_stamp = 0;
SG_color rgb = { 0, 0, 0 };
SG_color objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
int lineIdx = 0;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
for (int i = 0; i < linePtNum; i++)
{
SVzNL3DPosition* pt3D = &scanLines[line][i];
if (pt3D->pt3D.z < 1e-4)
pt3D->pt3D = { 0.0, 0.0, 0.0 };
int flag = pt3D->nPointIdx & 0xffff;
int highFlag = pt3D->nPointIdx >> 16;
int spacerFlag = highFlag & 0x4;
highFlag &= 0x3;
#if 0
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 5;
}
else
#endif
{
rgb = { 200, 200, 200 };
size = 1;
}
if (highFlag == 1)
{
rgb = { 250, 0, 0 };
size = 2;
}
else if (highFlag == 2)
{
rgb = { 0, 0, 250 };
size = 2;
}
if (spacerFlag > 0)
{
rgb = { 0, 250, 250 };
size = 2;
}
float x = (float)pt3D->pt3D.x;
float y = (float)pt3D->pt3D.y;
float z = (float)pt3D->pt3D.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
if (poseInfo.size() > 1e-4)
{
int objNum = (int)poseInfo.size();
sw << "Line_" << lineNum << "_0_" << objNum << std::endl;
lineNum++;
size = 20;
for (int m = 0; m < (int)poseInfo.size(); m++)
{
if (m == 0)
rgb = { 255, 0, 0 };
else
rgb = { 255, 255, 0 };
float x = (float)poseInfo[m].center.x;
float y = (float)poseInfo[m].center.y;
float z = (float)poseInfo[m].center.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
//输出方向线条
rgb = { 250, 0, 0 };
size = 2;
//double dirLen = 500;
for (int m = 0; m < (int)poseInfo.size(); m++)
{
if (poseInfo[m].workpieceType != 9)
{
SVzNL3DPoint dirPt1 = { poseInfo[m].center.x + poseInfo[m].z_dir.x * dirLen,
poseInfo[m].center.y + poseInfo[m].z_dir.y * dirLen,
poseInfo[m].center.z + poseInfo[m].z_dir.z * dirLen };
SVzNL3DPoint dirPt2 = { poseInfo[m].center.x - poseInfo[m].z_dir.x * dirLen,
poseInfo[m].center.y - poseInfo[m].z_dir.y * dirLen,
poseInfo[m].center.z - poseInfo[m].z_dir.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
else
{
SVzNL3DPoint dirPt1 = { poseInfo[m].center.x + poseInfo[m].z_dir.x * dirLen,
poseInfo[m].center.y + poseInfo[m].z_dir.y * dirLen,
poseInfo[m].center.z + poseInfo[m].z_dir.z * dirLen };
SVzNL3DPoint dirPt2 = { poseInfo[m].center.x - poseInfo[m].z_dir.x * dirLen,
poseInfo[m].center.y - poseInfo[m].z_dir.y * dirLen,
poseInfo[m].center.z - poseInfo[m].z_dir.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
double sapcerDirLen = 200;
dirPt1 = { poseInfo[m].center.x + poseInfo[m].x_dir.x * sapcerDirLen,
poseInfo[m].center.y + poseInfo[m].x_dir.y * sapcerDirLen,
poseInfo[m].center.z + poseInfo[m].x_dir.z * sapcerDirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << poseInfo[m].center.x << "," << poseInfo[m].center.y << "," << poseInfo[m].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt2 = { poseInfo[m].center.x + poseInfo[m].y_dir.x * sapcerDirLen,
poseInfo[m].center.y + poseInfo[m].y_dir.y * sapcerDirLen,
poseInfo[m].center.z + poseInfo[m].y_dir.z * sapcerDirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << poseInfo[m].center.x << "," << poseInfo[m].center.y << "," << poseInfo[m].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
}
if (binInfo)
{
rgb = { 0, 0, 250 };
//输出外接矩形
SVzNL3DPoint dirPt1 = binInfo->minRectVertex[0];
SVzNL3DPoint dirPt2 = binInfo->minRectVertex[1];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo->minRectVertex[1];
dirPt2 = binInfo->minRectVertex[2];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo->minRectVertex[2];
dirPt2 = binInfo->minRectVertex[3];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo->minRectVertex[3];
dirPt2 = binInfo->minRectVertex[0];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
}
sw.close();
}
void _outputRGBDResult_XYZ_RGBD_planningResult(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
WD_HRM_BinInfo& binInfo,
std::vector<WD_workpieceInfo>& posInfo,
const double workpieceHeight)
{
int objNumber = 0;
if (posInfo.size() > 0)
objNumber = 1;
int lineNum = (int)scanLines.size();
std::ofstream sw(fileName);
int realLines = (objNumber == 0) ? lineNum : (lineNum + 1);
sw << "LineNum:" << realLines << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int maxLineIndex = 0;
int max_stamp = 0;
SG_color rgb = { 0, 0, 0 };
SG_color objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
int lineIdx = 0;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
for (int i = 0; i < linePtNum; i++)
{
SVzNL3DPosition* pt3D = &scanLines[line][i];
if (pt3D->nPointIdx > 0)
int kkk = 1;
int flag = pt3D->nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 5;
}
else
{
rgb = { 200, 200, 200 };
size = 1;
}
float x = (float)pt3D->pt3D.x;
float y = (float)pt3D->pt3D.y;
float z = (float)pt3D->pt3D.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
}
if (posInfo.size() > 0)
{
int num = (int)posInfo.size();
sw << "Line_" << lineNum << "_0_" << num << std::endl;
lineNum++;
size = 20;
rgb = { 255, 255, 0 };
for(int m = 0; m <num;m ++)
{
float x = (float)posInfo[m].center.x;
float y = (float)posInfo[m].center.y;
float z = (float)posInfo[m].center.z;
sw << "{" << x << "," << y << "," << z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
}
//输出方向线条
rgb = { 250, 0, 0 };
size = 5;
double dirLen = workpieceHeight;
for (int m = 0; m < (int)posInfo.size(); m++)
{
SVzNL3DPoint dirPt1 = posInfo[m].center; //
SVzNL3DPoint dirPt2 = { posInfo[m].center.x - posInfo[m].z_dir.x * dirLen,
posInfo[m].center.y - posInfo[m].z_dir.y * dirLen,
posInfo[m].center.z - posInfo[m].z_dir.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
rgb = { 0, 0, 250 };
//输出外接矩形
SVzNL3DPoint dirPt1 = binInfo.minRectVertex[0];
SVzNL3DPoint dirPt2 = binInfo.minRectVertex[1];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo.minRectVertex[1];
dirPt2 = binInfo.minRectVertex[2];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo.minRectVertex[2];
dirPt2 = binInfo.minRectVertex[3];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt1 = binInfo.minRectVertex[3];
dirPt2 = binInfo.minRectVertex[0];
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt1.x << "," << dirPt1.y << "," << dirPt1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt2.x << "," << dirPt2.y << "," << dirPt2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
sw.close();
}
void _outputScanDataFile_vector(char* fileName, std::vector<std::vector<SVzNL3DPosition>>& scanLines, bool removeZeros, int* headNullLines)
{
std::ofstream sw(fileName);
int lineNum = (int)scanLines.size();
if (lineNum == 0)
return;
sw << "LineNum:" << lineNum << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int lineIdx = 0;
int null_lines = 0;
bool counterNull = true;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
if (true == removeZeros)
{
int vldPtNum = 0;
for (int i = 0; i < linePtNum; i++)
{
if (scanLines[line][i].pt3D.z > 1e-4)
vldPtNum++;
}
linePtNum = vldPtNum;
}
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
bool isNull = true;
for (int i = 0; i < linePtNum; i++)
{
SVzNL3DPoint* pt3D = &scanLines[line][i].pt3D;
if ((pt3D->z > 1e-4) && (isNull == true))
isNull = false;
if ((true == removeZeros) && (pt3D->z < 1e-4))
continue;
float x = (float)pt3D->x;
float y = (float)pt3D->y;
float z = (float)pt3D->z;
sw << "{ " << x << "," << y << "," << z << " }-";
sw << "{0,0}-{0,0}" << std::endl;
}
if (true == counterNull)
{
if (true == isNull)
null_lines++;
else
counterNull = false;
}
}
*headNullLines = null_lines;
sw.close();
}
void _outputScanDataFile_SVzNLPositionD(char* fileName, std::vector<std::vector<SVzNLPositionD>>& scanLines, bool removeZeros, int* headNullLines)
{
std::ofstream sw(fileName);
int lineNum = (int)scanLines.size();
if (lineNum == 0)
return;
sw << "LineNum:" << lineNum << std::endl;
sw << "DataType: 0" << std::endl;
sw << "ScanSpeed: 0" << std::endl;
sw << "PointAdjust: 1" << std::endl;
sw << "MaxTimeStamp: 0_0" << std::endl;
int lineIdx = 0;
int null_lines = 0;
bool counterNull = true;
for (int line = 0; line < lineNum; line++)
{
int linePtNum = (int)scanLines[line].size();
if (linePtNum == 0)
continue;
if (true == removeZeros)
{
int vldPtNum = 0;
for (int i = 0; i < linePtNum; i++)
{
if (scanLines[line][i].pt3D.z > 1e-4)
vldPtNum++;
}
linePtNum = vldPtNum;
}
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
bool isNull = true;
for (int i = 0; i < linePtNum; i++)
{
SVzNLPositionD& pt3D = scanLines[line][i];
if ((pt3D.pt3D.z > 1e-4) && (isNull == true))
isNull = false;
if ((true == removeZeros) && (pt3D.pt3D.z < 1e-4))
continue;
float x = (float)pt3D.pt3D.x;
float y = (float)pt3D.pt3D.y;
float z = (float)pt3D.pt3D.z;
sw << "{ " << x << "," << y << "," << z << " }-";
sw << "{ " << pt3D.ptLeft2D.x << "," << pt3D.ptLeft2D.y << " } - { " << pt3D.ptRight2D.x <<"," << pt3D.ptRight2D.y <<" }" << std::endl;
}
if (true == counterNull)
{
if (true == isNull)
null_lines++;
else
counterNull = false;
}
}
*headNullLines = null_lines;
sw.close();
}
void _outputWorkpieceInfo(char* fileName, std::vector< WD_workpieceInfo>& workpiecePositions)
{
std::ofstream sw(fileName);
char dataStr[250];
int number = (int)workpiecePositions.size();
for (int i = 0; i < number; i++)
{
//0:中央; 1-上边; 2-下边; 3-左边; 4-右边; 5-左上角; 6-右上角; 7-左下角; 8-右下角; 9-隔板
switch (workpiecePositions[i].workpieceType)
{
case 1:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 上边", i + 1, workpiecePositions[i].id);
break;
case 2:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 下边", i + 1, workpiecePositions[i].id);
break;
case 3:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 左边", i + 1, workpiecePositions[i].id);
break;
case 4:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 右边", i + 1, workpiecePositions[i].id);
break;
case 5:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 左上角", i + 1, workpiecePositions[i].id);
break;
case 6:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 右上角", i + 1, workpiecePositions[i].id);
break;
case 7:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 左下角", i + 1, workpiecePositions[i].id);
break;
case 8:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 右下角", i + 1, workpiecePositions[i].id);
break;
case 9:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 隔板", i + 1, workpiecePositions[i].id);
break;
default:
sprintf_s(dataStr, 250, "工件_%d: id=%d, type= 中央", i + 1, workpiecePositions[i].id);
break;
}
//sprintf_s(dataStr, 250, "工件_%d: id=%d, type=%d", i + 1, workpiecePositions[i].id, workpiecePositions[i].workpieceType);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " imgCenter: (%d, %d)", workpiecePositions[i].imgCenter.x, workpiecePositions[i].imgCenter.y);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpiecePositions[i].center.x, workpiecePositions[i].center.y, workpiecePositions[i].center.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", workpiecePositions[i].x_dir.x, workpiecePositions[i].x_dir.y, workpiecePositions[i].x_dir.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", workpiecePositions[i].y_dir.x, workpiecePositions[i].y_dir.y, workpiecePositions[i].y_dir.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " z_dir: (%g, %g, %g)", workpiecePositions[i].z_dir.x, workpiecePositions[i].z_dir.y, workpiecePositions[i].z_dir.z);
sw << dataStr << std::endl;
}
sw.close();
}
void _outputBinInfo(char* fileName, WD_HRM_BinInfo& binInfo)
{
std::ofstream sw(fileName);
char dataStr[250];
sprintf_s(dataStr, 50, " center: (%g, %g, %g)", binInfo.center.x, binInfo.center.y, binInfo.center.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " L: %g; W: %g", binInfo.length, binInfo.width);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " topZ: %g", binInfo.binTopZ);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " bottom_dir: (%g, %g, %g)", binInfo.bottomNormal.x, binInfo.bottomNormal.y, binInfo.bottomNormal.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", binInfo.x_dir.x, binInfo.x_dir.y, binInfo.x_dir.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", binInfo.y_dir.x, binInfo.y_dir.y, binInfo.y_dir.z);
sw << dataStr << std::endl;
for (int i = 0; i < 4; i++)
{
sprintf_s(dataStr, 50, " vertex: (%g, %g, %g)", binInfo.minRectVertex[i].x, binInfo.minRectVertex[i].y, binInfo.minRectVertex[i].z);
sw << dataStr << std::endl;
}
sw.close();
}
WD_HRM_BinInfo _readBinInfo(char* fileName)
{
//设置初始结果
WD_HRM_BinInfo binInfo;
memset(&binInfo, 0, sizeof(WD_HRM_BinInfo));
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return binInfo;
float x, y, z;
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " center: (%f, %f, %f)", &x, &y, &z);
binInfo.center = { x, y, z };
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " L: %lf; W: %lf", &binInfo.length, &binInfo.width);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " topZ: %lf", &binInfo.binTopZ);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " bottom_dir: (%lf, %lf, %lf)", &binInfo.bottomNormal.x, &binInfo.bottomNormal.y, &binInfo.bottomNormal.z);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " x_dir: (%lf, %lf, %lf)", &binInfo.x_dir.x, &binInfo.x_dir.y, &binInfo.x_dir.z);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " y_dir: (%lf, %lf, %lf)", &binInfo.y_dir.x, &binInfo.y_dir.y, &binInfo.y_dir.z);
for (int i = 0; i < 4; i++)
{
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " vertex: (%f, %f, %f)", &x, &y, &z);
binInfo.minRectVertex[i] = { x, y, z };
}
inputFile.close();
return binInfo;
}
void _outputWorkpieceInfo(char* fileName, WD_HRM_workpieceSizeInfo& workpieceInfo)
{
std::ofstream sw(fileName);
char dataStr[250];
sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpieceInfo.center.x, workpieceInfo.center.y, workpieceInfo.center.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " R: %g; H: %g", workpieceInfo.workpieceRadius, workpieceInfo.workpieceHeight);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " layerZ: %g", workpieceInfo.layerZValue);
sw << dataStr << std::endl;
sw.close();
}
WD_HRM_workpieceSizeInfo _readWorkpieceInfo(char* fileName)
{
//设置初始结果
WD_HRM_workpieceSizeInfo workpieceInfo;
memset(&workpieceInfo, 0, sizeof(WD_HRM_workpieceSizeInfo));
std::ifstream inputFile(fileName);
std::string linedata;
if (inputFile.is_open() == false)
return workpieceInfo;
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " center: (%lf, %lf, %lf)", &workpieceInfo.center.x, &workpieceInfo.center.y, &workpieceInfo.center.z);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " R: %lf; H: %lf", &workpieceInfo.workpieceRadius, &workpieceInfo.workpieceHeight);
std::getline(inputFile, linedata);
sscanf_s(linedata.c_str(), " layerZ: %lf", &workpieceInfo.layerZValue);
inputFile.close();
return workpieceInfo;
}
void _XOYprojection_XYZUV(
cv::Mat& img,
std::vector<std::vector< SVzNLPositionD>>& dataLines,
std::vector< WD_workpieceInfo>& holes,
const double scale,
const int sideWidth,
const SVzNLRangeD x_range,
const SVzNLRangeD y_range,
bool drawDirAngle,
const double dirAngleLen)
{
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNLPositionD>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNLPositionD& pt3D = a_line[i];
if (pt3D.pt3D.z < 1e-4)
continue;
int flag = pt3D.nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 1;
}
else
{
rgb = { 150, 150, 150 };
size = 1;
}
double x = pt3D.pt3D.x;
double y = pt3D.pt3D.y;
int px = (int)((x - x_range.min) / scale + sideWidth);
int py = (int)((y - y_range.min) / scale + sideWidth);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (holes.size() > 0)
{
for (int i = 0; i < (int)holes.size(); i++)
{
if (i == 0)
{
rgb = { 255, 0, 0 };
size = int(3.0 / scale);
}
else
{
rgb = { 255, 255, 0 };
size = int(3.0 / scale);
}
WD_workpieceInfo& a_hole = holes[i];
int px = (int)((a_hole.center.x - x_range.min) / scale + sideWidth);
int py = (int)((a_hole.center.y - y_range.min) / scale + sideWidth);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
rgb = { 0, 255, 0 };
size = int(2.0 / scale);
if (true == drawDirAngle)
{
//画线
double x1 = a_hole.center.x;
double y1 = a_hole.center.y;
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
//x轴
double x2 = a_hole.center.x + dirAngleLen * a_hole.x_dir.x;
double y2 = a_hole.center.y + dirAngleLen * a_hole.x_dir.y;
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 255, 0, 0 }; //x轴用红色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1);
//y轴
x2 = a_hole.center.x + dirAngleLen * a_hole.y_dir.x;
y2 = a_hole.center.y + dirAngleLen * a_hole.y_dir.y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 255, 0 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1);
//z轴
x2 = a_hole.center.x + dirAngleLen * a_hole.z_dir.x;
y2 = a_hole.center.y + dirAngleLen * a_hole.z_dir.y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //z轴用蓝色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1);
}
}
}
}
void EulerRpyToRotation1(const double rpy[3], double matrix3d[9]) {
double cos0 = cos(rpy[0] * PI / 180);
double sin0 = sin(rpy[0] * PI / 180);
double cos1 = cos(rpy[1] * PI / 180);
double sin1 = sin(rpy[1] * PI / 180);
double cos2 = cos(rpy[2] * PI / 180);
double sin2 = sin(rpy[2] * PI / 180);
matrix3d[0] = cos2 * cos1;
matrix3d[1] = cos2 * sin1 * sin0 - sin2 * cos0;
matrix3d[2] = cos2 * sin1 * cos0 + sin2 * sin0;
matrix3d[3] = sin2 * cos1;
matrix3d[4] = sin2 * sin1 * sin0 + cos2 * cos0;
matrix3d[5] = sin2 * sin1 * cos0 - cos2 * sin0;
matrix3d[6] = -sin1;
matrix3d[7] = cos1 * sin0;
matrix3d[8] = cos1 * cos0;
return;
}
void _rotateCloudPts_XYZUV(
std::vector<std::vector< SVzNLPositionD>>& scanLines,
double matrix3d[9],
std::vector<std::vector< SVzNLPositionD>>& rotateLines,
SVzNLRangeD& rx_range, SVzNLRangeD& ry_range)
{
int lineNum = (int)scanLines.size();
rotateLines.resize(lineNum);
rx_range.min = 0;
rx_range.max = -1;
ry_range.min = 0;
ry_range.max = -1;
for (int line = 0; line < lineNum; line++)
{
for (int i = 0; i < (int)scanLines[line].size(); i++)
{
SVzNLPositionD& pt3D = scanLines[line][i];
if (pt3D.pt3D.z < 1e-4)
continue;
SVzNLPositionD r_pt;
r_pt.pt3D = _ptRotate(pt3D.pt3D, matrix3d);
r_pt.nPointIdx = pt3D.nPointIdx;
r_pt.ptLeft2D = pt3D.ptLeft2D;
r_pt.ptRight2D = pt3D.ptRight2D;
rotateLines[line].push_back(r_pt);
if (rx_range.max < rx_range.min)
{
rx_range.min = r_pt.pt3D.x;
rx_range.max = r_pt.pt3D.x;
}
else
{
if (rx_range.min > r_pt.pt3D.x)
rx_range.min = r_pt.pt3D.x;
if (rx_range.max < r_pt.pt3D.x)
rx_range.max = r_pt.pt3D.x;
}
if (ry_range.max < ry_range.min)
{
ry_range.min = r_pt.pt3D.y;
ry_range.max = r_pt.pt3D.y;
}
else
{
if (ry_range.min > r_pt.pt3D.y)
ry_range.min = r_pt.pt3D.y;
if (ry_range.max < r_pt.pt3D.y)
ry_range.max = r_pt.pt3D.y;
}
}
}
}
void _genXOYProjectionImage_XYZUV(
cv::String& fileName,
std::vector<std::vector< SVzNLPositionD>>& scanLines,
const double scale,
std::vector< WD_workpieceInfo>& holes,
const double rpy[3], const double dirLen)
{
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
std::vector<WD_workpieceInfo> r_objOps;
r_objOps.resize(holes.size());
std::vector<std::vector< SVzNLPositionD>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts_XYZUV(scanLines, matrix3d, rotateLines, rx_range, ry_range);
//统计X和Y的范围
int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1;
if (x_cols % 2 == 1)
x_cols += 1;
int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1;
if (y_rows % 2 == 1)
y_rows += 1;
int sideWidth = 4;
int imgCols = x_cols + sideWidth * 2;
int imgRows = y_rows + sideWidth * 2;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection_XYZUV(img, rotateLines, r_objOps, scale, sideWidth, rx_range, ry_range, true, dirLen);
cv::imwrite(fileName, img);
return;
}
void _rotateCloudPts(
std::vector<std::vector< SVzNL3DPosition>>& scanLines,
double matrix3d[9],
std::vector<std::vector< SVzNL3DPosition>>& rotateLines,
SVzNLRangeD& rx_range, SVzNLRangeD& ry_range)
{
int lineNum = (int)scanLines.size();
rotateLines.resize(lineNum);
rx_range.min = 0;
rx_range.max = -1;
ry_range.min = 0;
ry_range.max = -1;
for (int line = 0; line < lineNum; line++)
{
for (int i = 0; i < (int)scanLines[line].size(); i++)
{
SVzNL3DPosition& pt3D = scanLines[line][i];
if (pt3D.pt3D.z < 1e-4)
continue;
SVzNL3DPosition r_pt;
r_pt.pt3D = _ptRotate(pt3D.pt3D, matrix3d);
r_pt.nPointIdx = pt3D.nPointIdx;
rotateLines[line].push_back(r_pt);
if (rx_range.max < rx_range.min)
{
rx_range.min = r_pt.pt3D.x;
rx_range.max = r_pt.pt3D.x;
}
else
{
if (rx_range.min > r_pt.pt3D.x)
rx_range.min = r_pt.pt3D.x;
if (rx_range.max < r_pt.pt3D.x)
rx_range.max = r_pt.pt3D.x;
}
if (ry_range.max < ry_range.min)
{
ry_range.min = r_pt.pt3D.y;
ry_range.max = r_pt.pt3D.y;
}
else
{
if (ry_range.min > r_pt.pt3D.y)
ry_range.min = r_pt.pt3D.y;
if (ry_range.max < r_pt.pt3D.y)
ry_range.max = r_pt.pt3D.y;
}
}
}
}
void _XOYprojection_binInfo(
cv::Mat& img,
std::vector<std::vector< SVzNL3DPosition>>& dataLines,
WD_HRM_BinInfo& binInfo,
const double scale,
const int sideWidth,
const SVzNLRangeD x_range,
const SVzNLRangeD y_range,
const double dirAngleLen)
{
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNL3DPosition>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNL3DPosition& pt3D = a_line[i];
if (pt3D.pt3D.z < 1e-4)
continue;
int flag = pt3D.nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 1;
}
else
{
rgb = { 150, 150, 150 };
size = 1;
}
double x = pt3D.pt3D.x;
double y = pt3D.pt3D.y;
int px = (int)((x - x_range.min) / scale + sideWidth);
int py = (int)((y - y_range.min) / scale + sideWidth);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (binInfo.center.z > 1e-4)
{
rgb = { 255, 0, 0 };
size = int(10.0 / scale);
int px = (int)((binInfo.center.x - x_range.min) / scale + sideWidth);
int py = (int)((binInfo.center.y - y_range.min) / scale + sideWidth);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
//画线
double x1 = binInfo.center.x;
double y1 = binInfo.center.y;
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
//x轴
double mx2 = binInfo.center.x - dirAngleLen * binInfo.x_dir.x;
double my2 = binInfo.center.y - dirAngleLen * binInfo.x_dir.y;
int mpx2 = (int)((mx2 - x_range.min) / scale + sideWidth);
int mpy2 = (int)((my2 - y_range.min) / scale + sideWidth);
double x2 = binInfo.center.x + dirAngleLen * binInfo.x_dir.x;
double y2 = binInfo.center.y + dirAngleLen * binInfo.x_dir.y;
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 255, 0, 0 }; //x轴用红色
cv::line(img, cv::Point(mpx2, mpy2), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1);
//y轴
x2 = binInfo.center.x + dirAngleLen * binInfo.y_dir.x;
y2 = binInfo.center.y + dirAngleLen * binInfo.y_dir.y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 255, 0 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 1);
//边1
x1 = binInfo.minRectVertex[0].x;
y1 = binInfo.minRectVertex[0].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[1].x;
y2 = binInfo.minRectVertex[1].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边2
x1 = binInfo.minRectVertex[1].x;
y1 = binInfo.minRectVertex[1].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[2].x;
y2 = binInfo.minRectVertex[2].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边3
x1 = binInfo.minRectVertex[2].x;
y1 = binInfo.minRectVertex[2].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[3].x;
y2 = binInfo.minRectVertex[3].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边4
x1 = binInfo.minRectVertex[3].x;
y1 = binInfo.minRectVertex[3].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[0].x;
y2 = binInfo.minRectVertex[0].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
}
void _genXOYProjectionImage_binInfo(
cv::String& fileName,
std::vector<std::vector< SVzNL3DPosition>>& scanLines,
const double scale,
WD_HRM_BinInfo& binInfo,
const double rpy[3], const double dirLen)
{
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
WD_HRM_BinInfo rotateBin;
rotateBin.length = binInfo.length;
rotateBin.width = binInfo.width;
rotateBin.center = _ptRotate(binInfo.center, matrix3d);
rotateBin.bottomNormal = _ptRotate(binInfo.bottomNormal, matrix3d);
rotateBin.x_dir = _ptRotate(binInfo.x_dir, matrix3d);
rotateBin.y_dir = _ptRotate(binInfo.y_dir, matrix3d);
for (int i = 0; i < 4; i++)
rotateBin.minRectVertex[i] = _ptRotate(binInfo.minRectVertex[i], matrix3d);
std::vector<std::vector< SVzNL3DPosition>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range);
//统计X和Y的范围
int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1;
if (x_cols % 2 == 1)
x_cols += 1;
int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1;
if (y_rows % 2 == 1)
y_rows += 1;
int sideWidth = 32;
int imgCols = x_cols + sideWidth * 2;
int imgRows = y_rows + sideWidth * 2;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection_binInfo(img, rotateLines, rotateBin, scale, sideWidth, rx_range, ry_range, dirLen);
cv::imwrite(fileName, img);
return;
}
void _XOYprojection_workpieceInfo(
cv::Mat& img,
std::vector<std::vector< SVzNL3DPosition>>& dataLines,
std::vector<WD_workpieceInfo>& workpieceInfo,
std::vector<SVzNL3DPoint>& binRectVertex,
const double scale,
const int sideWidth,
const SVzNLRangeD x_range,
const SVzNLRangeD y_range,
const double dirAngleLen)
{
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNL3DPosition>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNL3DPosition& pt3D = a_line[i];
if (pt3D.pt3D.z < 1e-4)
continue;
int flag = pt3D.nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 1;
}
else
{
rgb = { 150, 150, 150 };
size = 1;
}
double x = pt3D.pt3D.x;
double y = pt3D.pt3D.y;
int px = (int)((x - x_range.min) / scale + sideWidth);
int py = (int)((y - y_range.min) / scale + sideWidth);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (workpieceInfo.size() > 0)
{
for (int i = 0; i < (int)workpieceInfo.size(); i++)
{
if (i == 0)
rgb = { 255, 0, 0 };
else
rgb = { 255, 255, 0 };
size = int(10.0 / scale);
int px = (int)((workpieceInfo[i].center.x - x_range.min) / scale + sideWidth);
int py = (int)((workpieceInfo[i].center.y - y_range.min) / scale + sideWidth);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
//画圆
rgb = { 0, 0, 255 };
size = (int)(workpieceInfo[i].value / scale);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
}
if (binRectVertex.size() == 4)
{
for (int i = 0; i < 4; i++)
{
int idx_0 = i;
int idx_1 = (i + 1) % 4;
double x1 = binRectVertex[idx_0].x;
double y1 = binRectVertex[idx_0].y;
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
double x2 = binRectVertex[idx_1].x;
double y2 = binRectVertex[idx_1].y;
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
}
}
void _genXOYProjectionImage_workpieceInfo(
cv::String& fileName,
std::vector<std::vector< SVzNL3DPosition>>& scanLines,
const double scale,
std::vector<WD_workpieceInfo>& workpieceInfo,
WD_HRM_BinInfo* binInfo,
const double rpy[3], const double dirLen)
{
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
std::vector<WD_workpieceInfo> rotatedWorkpiece;
for (int i = 0; i < (int)workpieceInfo.size(); i++)
{
WD_workpieceInfo rotateObj;
rotateObj.workpieceType = workpieceInfo[i].workpieceType;
rotateObj.value = workpieceInfo[i].value;
rotateObj.center = _ptRotate(workpieceInfo[i].center, matrix3d);
rotateObj.z_dir = _ptRotate(workpieceInfo[i].z_dir, matrix3d);
rotateObj.x_dir = _ptRotate(workpieceInfo[i].x_dir, matrix3d);
rotateObj.y_dir = _ptRotate(workpieceInfo[i].y_dir, matrix3d);
rotatedWorkpiece.push_back(rotateObj);
}
std::vector<std::vector< SVzNL3DPosition>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range);
std::vector<SVzNL3DPoint> binRectVertex;//最小外接矩形顶点
if (binInfo)
{
binRectVertex.resize(4);
for (int i = 0; i < 4; i++)
{
binRectVertex[i] = _ptRotate(binInfo->minRectVertex[i], matrix3d);
if (rx_range.max < rx_range.min)
{
rx_range.min = binRectVertex[i].x;
rx_range.max = binRectVertex[i].x;
}
else
{
if (rx_range.min > binRectVertex[i].x)
rx_range.min = binRectVertex[i].x;
if (rx_range.max < binRectVertex[i].x)
rx_range.max = binRectVertex[i].x;
}
if (ry_range.max < ry_range.min)
{
ry_range.min = binRectVertex[i].y;
ry_range.max = binRectVertex[i].y;
}
else
{
if (ry_range.min > binRectVertex[i].y)
ry_range.min = binRectVertex[i].y;
if (ry_range.max < binRectVertex[i].y)
ry_range.max = binRectVertex[i].y;
}
}
}
int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1;
if (x_cols % 2 == 1)
x_cols += 1;
int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1;
if (y_rows % 2 == 1)
y_rows += 1;
int sideWidth = 32;
int imgCols = x_cols + sideWidth * 2;
int imgRows = y_rows + sideWidth * 2;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection_workpieceInfo(img, rotateLines, rotatedWorkpiece, binRectVertex, scale, sideWidth, rx_range, ry_range, dirLen);
cv::imwrite(fileName, img);
return;
}
void _XOYprojection_planningResult(
cv::Mat& img,
std::vector<std::vector< SVzNL3DPosition>>& dataLines,
std::vector<WD_workpieceInfo>& workpieceInfo,
WD_HRM_BinInfo& binInfo,
const double scale,
const int sideWidth,
const SVzNLRangeD x_range,
const SVzNLRangeD y_range,
const double dirAngleLen)
{
cv::Vec3b rgb = cv::Vec3b(0, 0, 0);
cv::Vec3b objColor[8] = {
{245,222,179},//淡黄色
{210,105, 30},//巧克力色
{240,230,140},//黄褐色
{135,206,235},//天蓝色
{250,235,215},//古董白
{189,252,201},//薄荷色
{221,160,221},//梅红色
{188,143,143},//玫瑰红色
};
int size = 1;
for (int line = 0; line < dataLines.size(); line++)
{
std::vector< SVzNL3DPosition>& a_line = dataLines[line];
for (int i = 0; i < a_line.size(); i++)
{
SVzNL3DPosition& pt3D = a_line[i];
if (pt3D.pt3D.z < 1e-4)
continue;
int flag = pt3D.nPointIdx & 0xffff;
if (flag > 0)
{
rgb = objColor[flag % 8]; // { 255, 97, 0 };
size = 1;
}
else
{
rgb = { 150, 150, 150 };
size = 1;
}
double x = pt3D.pt3D.x;
double y = pt3D.pt3D.y;
int px = (int)((x - x_range.min) / scale + sideWidth);
int py = (int)((y - y_range.min) / scale + sideWidth);
if (size == 1)
img.at<cv::Vec3b>(py, px) = cv::Vec3b(rgb[2], rgb[1], rgb[0]);
else
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
}
if (workpieceInfo.size() > 0)
{
for (int i = 0; i < (int)workpieceInfo.size(); i++)
{
rgb = { 255, 0, 0 };
size = int(10.0 / scale);
int px = (int)((workpieceInfo[i].center.x - x_range.min) / scale + sideWidth);
int py = (int)((workpieceInfo[i].center.y - y_range.min) / scale + sideWidth);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
//画圆
rgb = { 0, 0, 255 };
size = (int)(workpieceInfo[i].value / scale);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
//边1
double x1 = binInfo.minRectVertex[0].x;
double y1 = binInfo.minRectVertex[0].y;
int px1 = (int)((x1 - x_range.min) / scale + sideWidth);
int py1 = (int)((y1 - y_range.min) / scale + sideWidth);
double x2 = binInfo.minRectVertex[1].x;
double y2 = binInfo.minRectVertex[1].y;
int px2 = (int)((x2 - x_range.min) / scale + sideWidth);
int py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边2
x1 = binInfo.minRectVertex[1].x;
y1 = binInfo.minRectVertex[1].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[2].x;
y2 = binInfo.minRectVertex[2].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边3
x1 = binInfo.minRectVertex[2].x;
y1 = binInfo.minRectVertex[2].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[3].x;
y2 = binInfo.minRectVertex[3].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
//边4
x1 = binInfo.minRectVertex[3].x;
y1 = binInfo.minRectVertex[3].y;
px1 = (int)((x1 - x_range.min) / scale + sideWidth);
py1 = (int)((y1 - y_range.min) / scale + sideWidth);
x2 = binInfo.minRectVertex[0].x;
y2 = binInfo.minRectVertex[0].y;
px2 = (int)((x2 - x_range.min) / scale + sideWidth);
py2 = (int)((y2 - y_range.min) / scale + sideWidth);
rgb = { 0, 0, 255 }; //y轴用绿色
cv::line(img, cv::Point(px1, py1), cv::Point(px2, py2), cv::Scalar(rgb[2], rgb[1], rgb[0]), 2);
}
}
void _genXOYProjectionImage_planningResult(
cv::String& fileName,
std::vector<std::vector< SVzNL3DPosition>>& scanLines,
const double scale,
WD_HRM_BinInfo& binInfo,
std::vector<WD_workpieceInfo>& workpieceInfo,
const double rpy[3], const double dirLen)
{
//旋转视角显示
double matrix3d[9];
EulerRpyToRotation1(rpy, matrix3d);
std::vector<WD_workpieceInfo> rotatedWorkpiece;
for (int i = 0; i < (int)workpieceInfo.size(); i++)
{
WD_workpieceInfo rotateObj;
rotateObj.workpieceType = workpieceInfo[i].workpieceType;
rotateObj.value = workpieceInfo[i].value;
rotateObj.center = _ptRotate(workpieceInfo[i].center, matrix3d);
rotateObj.z_dir = _ptRotate(workpieceInfo[i].z_dir, matrix3d);
rotateObj.x_dir = _ptRotate(workpieceInfo[i].x_dir, matrix3d);
rotateObj.y_dir = _ptRotate(workpieceInfo[i].y_dir, matrix3d);
rotatedWorkpiece.push_back(rotateObj);
}
std::vector<std::vector< SVzNL3DPosition>> rotateLines;
SVzNLRangeD rx_range, ry_range;
_rotateCloudPts(scanLines, matrix3d, rotateLines, rx_range, ry_range);
//统计X和Y的范围
int x_cols = (int)((rx_range.max - rx_range.min) / scale) + 1;
if (x_cols % 2 == 1)
x_cols += 1;
int y_rows = (int)((ry_range.max - ry_range.min) / scale) + 1;
if (y_rows % 2 == 1)
y_rows += 1;
int sideWidth = 32;
int imgCols = x_cols + sideWidth * 2;
int imgRows = y_rows + sideWidth * 2;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection_planningResult(img, rotateLines, rotatedWorkpiece, binInfo, scale, sideWidth, rx_range, ry_range, dirLen);
cv::imwrite(fileName, img);
return;
}
void zPassThroughFilter(std::vector<std::vector< SVzNL3DPosition>>& scanData, const SVzNLRangeD zRange)
{
for (int i = 0; i < (int)scanData.size(); i++)
{
for (int j = 0; j < (int)scanData[i].size(); j++)
{
if ((scanData[i][j].pt3D.z < zRange.min) || (scanData[i][j].pt3D.z > zRange.max))
scanData[i][j].pt3D = { 0.0, 0.0, 0.0 };
}
}
return;
}
//拓普发工件孔定位(工件定位)
#define HRM_TaperedWorkpiece_TEST_GROUP 1
void HaiRuiMa_TaperedWorkpiece_test(void)
{
const char* dataPath[HRM_TaperedWorkpiece_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/锥形工作2D+3D数据/数据1/", //0
};
SVzNLRange fileIdx[HRM_TaperedWorkpiece_TEST_GROUP] = {
{1,21},
};
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s\n", ver);
for (int grp = 0; grp < HRM_TaperedWorkpiece_TEST_GROUP; grp++)
{
SSG_planeCalibPara groundCalibPara;
//初始化成单位阵
groundCalibPara.planeCalib[0] = 1.0;
groundCalibPara.planeCalib[1] = 0.0;
groundCalibPara.planeCalib[2] = 0.0;
groundCalibPara.planeCalib[3] = 0.0;
groundCalibPara.planeCalib[4] = 1.0;
groundCalibPara.planeCalib[5] = 0.0;
groundCalibPara.planeCalib[6] = 0.0;
groundCalibPara.planeCalib[7] = 0.0;
groundCalibPara.planeCalib[8] = 1.0;
groundCalibPara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i];
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
//groundCalibPara = _readCalibPara(calibFile);
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =3;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNLPositionD>> scanLines;
vzReadLaserScanPointFromFile_XYZUV_vector(_scan_file, scanLines);
_removeZeroLines_XYZUV(scanLines);
if (scanLines.size() == 0)
continue;
sprintf_s(_scan_file, "%s%d_result.txt", dataPath[grp], fidx);
std::vector<WD_objArea2D> objROIs;
vzReadObj2DROI_1(_scan_file, objROIs);
long t1 = (long)GetTickCount64();//统计时间
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositions;
wd_HRM_TaperedWorkpiecePositioning(
scanLines,
objROIs,
groundCalibPara,
workpiecePositions,
&errCode);
long t2 = (long)GetTickCount64();
if (errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留!\n", _scan_file, (int)(t2 - t1));
else if (errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品!\n", _scan_file, (int)(t2 - t1));
else
printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode);
//输出测试结果
sprintf_s(_scan_file, "%sresult/LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_XYZUV_RGBD(_scan_file, scanLines, workpiecePositions);
sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositions);
#if 0
sprintf_s(calibFile, "%sresult/LaserLine%d_holes_projection.png", dataPath[grp], fidx);
double rpy[3] = { -30, 15, 0 }; //{ 0,-45, 0 }; //
double angleDrawLen = 15;
double displayScale = 0.3;
cv::String imgName(calibFile);
_genXOYProjectionImage(imgName, scanLines, displayScale, workpiecePositions, rpy, angleDrawLen);
#endif
printf("done\n");
for (int i = 0; i < (int)workpiecePositions.size(); i++)
printf(" objID_%d: (%f, %f, %f)\n", workpiecePositions[i].id, (float)workpiecePositions[i].center.x, (float)workpiecePositions[i].center.y, (float)workpiecePositions[i].center.z);
}
}
}
//地面调平
#define HRM_GroundCalib_TEST_GROUP 1
void HaiRuiMa_groundCalib_test(void)
{
#if 0
const char* dataPath[HRM_GroundCalib_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2
};
SVzNLRange fileIdx[HRM_GroundCalib_TEST_GROUP] = {
{1,7}, {1,9}, {1,7},
};
#else
const char* dataPath[HRM_GroundCalib_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/WorkpieceRotor/", //0
};
SVzNLRange fileIdx[HRM_GroundCalib_TEST_GROUP] = {
{3,3},
};
#endif
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s\n", ver);
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/2026-09-海瑞马/09-14中/调平.txt");
int lineNum = 0;
float lineV = 0.0f;
int dataCalib = 0;
int maxTimeStamp = 0;
int clockPerSecond = 0;
std::vector<std::vector< SVzNL3DPosition>> scanData;
vzReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanData);
lineNum = (int)scanData.size();
if (scanData.size() > 0)
{
#if 1
//过滤背景数据
SVzNLRangeD validZRange = { 100.0, 2500.0 };
zPassThroughFilter(scanData, validZRange);
#endif
SSG_planeCalibPara calibPara = wd_getGroundCalibPara(scanData);
//
char calibFile[250];
sprintf_s(calibFile, "F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/2026-09-海瑞马/09-14中/ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
#if 0
for (int grp = 0; grp < HRM_GroundCalib_TEST_GROUP; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
#if 0
//fidx =4;
char _scan_file[256];
sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
lineNum = (int)scanLines.size();
for (int i = 0; i < lineNum; i++)
wd_lineDataR(scanLines[i], calibPara.planeCalib, -1);//调平,去除地面
sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177_ground_calibrated.txt", dataPath[grp], fidx);
int headNullLines = 0;
_outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines);
sprintf_s(_scan_file, "%s工件%d_LaserData_Jl26C177.txt", dataPath[grp], fidx);
scanLines.clear();
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
lineNum = (int)scanLines.size();
for (int i = 0; i < lineNum; i++)
wd_lineDataR(scanLines[i], calibPara.planeCalib, -1);//调平,去除地面
sprintf_s(_scan_file, "%s工件%d_LaserData_Jl26C177_ground_calibrated.txt", dataPath[grp], fidx);
headNullLines = 0;
_outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines);
#else
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
lineNum = (int)scanLines.size();
for (int i = 0; i < lineNum; i++)
wd_lineDataR(scanLines[i], calibPara.planeCalib, -1);//调平,去除地面
sprintf_s(_scan_file, "%s%d_cloud_ground_calibrated.txt", dataPath[grp], fidx);
int headNullLines = 0;
_outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines);
#endif
printf("%s: calib done!\n", _scan_file);
}
}
#endif
printf("all calib done!\n", _calib_datafile);
}
}
//拓普发工件孔定位(工件定位)
#define HRM_RotorCore_TEST_GROUP 5
void HaiRuiMa_rotorCorePositioning_test(void)
{
const char* dataPath[HRM_RotorCore_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据2D3D/", //0
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/WorkpieceRotor/", //1
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/现场数据/", //2
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/2026-09-海瑞马/09-14/", //3
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/2026-09-海瑞马/09-14中/", //4
};
SVzNLRange fileIdx[HRM_RotorCore_TEST_GROUP] = {
{1,10}, {3,70},{2,2}, {1,47}, {1,54}
};
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s\n", ver);
for (int grp = 3; grp < HRM_RotorCore_TEST_GROUP; grp++)
{
SSG_planeCalibPara groundCalibPara;
//初始化成单位阵
groundCalibPara.planeCalib[0] = 1.0;
groundCalibPara.planeCalib[1] = 0.0;
groundCalibPara.planeCalib[2] = 0.0;
groundCalibPara.planeCalib[3] = 0.0;
groundCalibPara.planeCalib[4] = 1.0;
groundCalibPara.planeCalib[5] = 0.0;
groundCalibPara.planeCalib[6] = 0.0;
groundCalibPara.planeCalib[7] = 0.0;
groundCalibPara.planeCalib[8] = 1.0;
groundCalibPara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i];
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
groundCalibPara = _readCalibPara(calibFile);
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 50;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNLPositionD>> scanLines;
vzReadLaserScanPointFromFile_XYZUV_vector(_scan_file, scanLines);
_removeZeroLines_XYZUV(scanLines);
if (scanLines.size() == 0)
continue;
#if 0
int headNullLines = 0;
sprintf_s(_scan_file, "%s%d_cloud.txt", dataPath[grp], fidx);
_outputScanDataFile_SVzNLPositionD(_scan_file, scanLines, false, &headNullLines);
continue;
#endif
WD_HRM_BinInfo binInfo;
#if 0
if (grp == 1)
{
std::vector< std::vector<SVzNL3DPosition>> scanData;
scanData.resize(scanLines.size());
for (int line = 0; line < (int)scanLines.size(); line++)
{
scanData[line].resize(scanLines[line].size());
for (int j = 0; j < (int)scanLines[line].size(); j++)
{
scanData[line][j].nPointIdx = scanLines[line][j].nPointIdx;
scanData[line][j].pt3D = scanLines[line][j].pt3D;
}
}
int rCode = 0;
double binHeight = 640; //料筐最上边沿距地面高度
double zSliceRange = 50.0; //取料筐最上边沿的Z切片范围
binInfo = wd_HRM_getBinSize(scanData, groundCalibPara, binHeight, zSliceRange, &rCode);
}
else if(grp == 0)
{
//读取料筐参数
sprintf_s(calibFile, "%sbin_info.txt", dataPath[grp]);
binInfo = _readBinInfo(calibFile);
}
#endif
if( (grp >=3) && (grp <= 4))
sprintf_s(_scan_file, "%s%d_origin_result.txt", dataPath[grp], fidx);
else
sprintf_s(_scan_file, "%s%d_result.txt", dataPath[grp], fidx);
std::vector<WD_objArea2D> objROIs;
if( ((grp == 0) && (fidx <= 9)) || ((grp >=3)&&(grp<=4)))
vzReadObj2DROI(_scan_file, objROIs);
else
vzReadObj2DROI_1(_scan_file, objROIs);
SWD_Cylinder workpieceParam; //圆柱形工件的标称半径和高度
if (grp == 3)
{
workpieceParam.radius = 60.0;
workpieceParam.height = 70.0;
}
else if (grp == 4)
{
workpieceParam.radius = 42.0;
workpieceParam.height = 50.0;
}
else
{
workpieceParam.radius = 45.0;
workpieceParam.height = 20.0;
}
SVzNLSizeD spacerParam; //隔板参数:长和宽
spacerParam.dWidth = 720.0;
spacerParam.dHeight = 510.0;
double layerRatio = 0.5; //分层系数,分层门限=分层系数*工件高度;当两个工件的高度差大于分层门限时,判断为在不同层
const double distToSideRatio = 1.1; //边距系数,边距门限=边距系数*工件直径;当工件距边的距离大于边距门限时,判断为边上的工件
double groundRemoveOffset = 200; //料筐地面去除的Z偏置,实际地面去除高度为 groundCalibPara.planeHeight - groundRemoveOffset
long t1 = (long)GetTickCount64();//统计时间
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositions;
std::vector<std::vector<SVzNL3DPosition>> debugScanLines;
wd_HRM_RotorCorePositioning(
scanLines,
objROIs,
groundCalibPara,
spacerParam,
workpieceParam,
layerRatio,
distToSideRatio,
groundRemoveOffset,
workpiecePositions,
binInfo,
#ifdef _OUTPUT_DEBUG_DATA
debugScanLines,
#endif
&errCode);
long t2 = (long)GetTickCount64();
if (errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留!\n", _scan_file, (int)(t2 - t1));
else if (errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品!\n", _scan_file, (int)(t2 - t1));
else
{
int num = (int)workpiecePositions.size();
if(num == 0)
printf("%s: %d(ms), errCode=%d 结果: 0 ...", _scan_file, (int)(t2 - t1), errCode);
else if( (num == 1) && (workpiecePositions[0].workpieceType == 9))
printf("%s: %d(ms), errCode=%d 结果: 隔板 ...", _scan_file, (int)(t2 - t1), errCode);
else
printf("%s: %d(ms), errCode=%d 结果: %d...", _scan_file, (int)(t2 - t1), errCode, num);
}
//输出测试结果
sprintf_s(calibFile, "%sresult/LaserLine%d_workpiece_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositions);
//旋转到调平坐标系
int workpieceNum = (int)workpiecePositions.size();
for (int i = 0; i < workpieceNum; i++)
{
SVzNL3DPoint rpt;
rpt = wd_ptRotate(workpiecePositions[i].center, groundCalibPara.planeCalib);
workpiecePositions[i].center = rpt;
rpt = wd_ptRotate(workpiecePositions[i].y_dir, groundCalibPara.planeCalib);
workpiecePositions[i].y_dir = rpt;
rpt = wd_ptRotate(workpiecePositions[i].z_dir, groundCalibPara.planeCalib);
workpiecePositions[i].z_dir = rpt;
rpt = wd_ptRotate(workpiecePositions[i].x_dir, groundCalibPara.planeCalib);
workpiecePositions[i].x_dir = rpt;
}
sprintf_s(_scan_file, "%sresult/result_%d.txt", dataPath[grp], fidx);
_outputRGBDResult_XYZ_RGBD_workpieceInfo(_scan_file, debugScanLines, workpiecePositions, &binInfo, 50);
#if 1
sprintf_s(calibFile, "%sresult/result_%d_projection.png", dataPath[grp], fidx);
double rpy[3] = { 0, 0, 0 }; //{ 0,-45, 0 }; //
double angleDrawLen = 15;
double displayScale = 0.3;
cv::String imgName(calibFile);
_genXOYProjectionImage_workpieceInfo(imgName, debugScanLines, displayScale, workpiecePositions, &binInfo, rpy, angleDrawLen);
#endif
printf("done\n");
}
}
}
#define HRM_BIN_TEST_GROUP 3
//海瑞马料筐尺寸计算
void HaiRuiMa_BinSizeCompute_test(void)
{
const char* dataPath[HRM_BIN_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2
};
SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = {
{1,7}, {1,9}, {1,7},
};
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s 料筐尺寸计算\n", ver);
for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++)
{
SSG_planeCalibPara groundCalibPara;
//初始化成单位阵
groundCalibPara.planeCalib[0] = 1.0;
groundCalibPara.planeCalib[1] = 0.0;
groundCalibPara.planeCalib[2] = 0.0;
groundCalibPara.planeCalib[3] = 0.0;
groundCalibPara.planeCalib[4] = 1.0;
groundCalibPara.planeCalib[5] = 0.0;
groundCalibPara.planeCalib[6] = 0.0;
groundCalibPara.planeCalib[7] = 0.0;
groundCalibPara.planeCalib[8] = 1.0;
groundCalibPara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i];
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
groundCalibPara = _readCalibPara(calibFile);
double binHeight = 640; //料筐最上边沿距地面高度
double zSliceRange = 5.0; //取料筐最上边沿的Z切片范围
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 15;
char _scan_file[256];
sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
int errCode = 0;
#if 0
SSG_cornerParam cornerParam;
cornerParam.cornerTh = 60; //45度角
cornerParam.scale = 10; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
cornerParam.minEndingGap = 10; // algoParam.bagParam.bagW / 4;
cornerParam.minEndingGap_z = 5.0;
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
cornerParam.jumpCornerTh_2 = 60;
//料筐码放:获取料筐尺寸、料筐姿态、料筐中心点坐标
WD_HRM_BinInfo binInfo = wd_HRM_getBinSize(
scanLines,
cornerParam,
&errCode);
#else
//料筐码放:获取料筐尺寸、料筐姿态、料筐中心点坐标
WD_HRM_BinInfo binInfo = wd_HRM_getBinSize(
scanLines,
groundCalibPara,
binHeight, //料筐高度
zSliceRange,
&errCode);
#endif
long t2 = (long)GetTickCount64();
printf("%s: %d(ms), errCode=%d ...", _scan_file, (int)(t2 - t1), errCode);
//输出测试结果
sprintf_s(_scan_file, "%sresult/LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_XYZ_RGBD_binInfo(_scan_file, scanLines, binInfo);
sprintf_s(_scan_file, "%sresult/%d_bin_info.txt", dataPath[grp], fidx);
_outputBinInfo(_scan_file, binInfo);
sprintf_s(calibFile, "%sresult/LaserLine%d_bin_projection.png", dataPath[grp], fidx);
double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; //
double angleDrawLen = 500;
double displayScale = 1.0;
cv::String imgName(calibFile);
_genXOYProjectionImage_binInfo(imgName, scanLines, displayScale, binInfo, rpy, angleDrawLen);
printf("done\n");
}
}
}
//海瑞马工件尺寸测量
void HaiRuiMa_workpieceSizeCompute_test(void)
{
const char* dataPath[HRM_BIN_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2
};
SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = {
{1,7}, {1,9}, {1,7},
};
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s 工件尺寸测量 \n", ver);
for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++)
{
SSG_planeCalibPara groundCalibPara;
//初始化成单位阵
groundCalibPara.planeCalib[0] = 1.0;
groundCalibPara.planeCalib[1] = 0.0;
groundCalibPara.planeCalib[2] = 0.0;
groundCalibPara.planeCalib[3] = 0.0;
groundCalibPara.planeCalib[4] = 1.0;
groundCalibPara.planeCalib[5] = 0.0;
groundCalibPara.planeCalib[6] = 0.0;
groundCalibPara.planeCalib[7] = 0.0;
groundCalibPara.planeCalib[8] = 1.0;
groundCalibPara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i];
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
groundCalibPara = _readCalibPara(calibFile);
double binHeight = 640; //料筐最上边沿距地面高度
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 15;
char _scan_file[256];
sprintf_s(_scan_file, "%s工件%d_LaserData_Jl26C177.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
int errCode = 0;
SSG_cornerParam cornerParam;
cornerParam.cornerTh = 60; //45度角
cornerParam.scale = 10; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
cornerParam.minEndingGap = 10; // algoParam.bagParam.bagW / 4;
cornerParam.minEndingGap_z = 5.0;
cornerParam.jumpCornerTh_1 = 15; //水平角度,小于此角度视为水平
cornerParam.jumpCornerTh_2 = 60;
//标准工件尺寸。目前3种工件尺寸
std::vector<WD_HRM_workpieceSizeInfo> standardWorkpieceSize;
standardWorkpieceSize.resize(3);
//工件1
standardWorkpieceSize[0].center = { 0, 0, 0 };
standardWorkpieceSize[0].layerZValue = 0;
standardWorkpieceSize[0].workpieceHeight = 40.0;
standardWorkpieceSize[0].workpieceRadius = 45.0;
//工件2
standardWorkpieceSize[1].center = { 0, 0, 0 };
standardWorkpieceSize[1].layerZValue = 0;
standardWorkpieceSize[1].workpieceHeight = 70.0;
standardWorkpieceSize[1].workpieceRadius = 45.0;
//工件3
standardWorkpieceSize[2].center = { 0, 0, 0 };
standardWorkpieceSize[2].layerZValue = 0;
standardWorkpieceSize[2].workpieceHeight = 60.0;
standardWorkpieceSize[2].workpieceRadius = 62.5;
//料筐码放:获取工件尺寸
WD_HRM_workpieceSizeInfo workpieceInfo = wd_HRM_getWorkpieceSize(
scanLines,
standardWorkpieceSize,
cornerParam,
groundCalibPara,
&errCode);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms), R=%f, H=%f, errCode=%d ...", _scan_file, (int)(t2 - t1), workpieceInfo.workpieceRadius, workpieceInfo.workpieceHeight, errCode);
//输出测试结果
sprintf_s(_scan_file, "%sresult/LaserLine%d_workpiece_result.txt", dataPath[grp], fidx);
std::vector<WD_workpieceInfo> poseInfo;
WD_workpieceInfo a_pose;
memset(&a_pose, 0, sizeof(WD_workpieceInfo));
a_pose.center = workpieceInfo.center;
a_pose.value = workpieceInfo.workpieceRadius;
a_pose.z_dir = { 0, 0, 1.0 };
poseInfo.push_back(a_pose);
_outputRGBDResult_XYZ_RGBD_workpieceInfo(_scan_file, scanLines, poseInfo, NULL, 500);
sprintf_s(_scan_file, "%sresult/%d_workpiece_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(_scan_file, workpieceInfo);
sprintf_s(calibFile, "%sresult/LaserLine%d_workpiece_projection.png", dataPath[grp], fidx);
double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; //
double angleDrawLen = 500;
double displayScale = 1.0;
cv::String imgName(calibFile);
_genXOYProjectionImage_workpieceInfo(imgName, scanLines, displayScale, poseInfo, NULL, rpy, angleDrawLen);
printf("done\n");
}
}
}
//海瑞马码垛规划
void HaiRuiMa_positionPlanning_test(void)
{
const char* dataPath[HRM_BIN_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件1/", //0
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件2/", //1
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/码垛规划/数据2/工件3/", //2
};
SVzNLRange fileIdx[HRM_BIN_TEST_GROUP] = {
{1,7}, {1,9}, {1,7},
};
const char* ver = wd_hybridPositioningVersion();
printf("ver:%s 码垛规划\n", ver);
for (int grp = 0; grp < HRM_BIN_TEST_GROUP; grp++)
{
SSG_planeCalibPara groundCalibPara;
//初始化成单位阵
groundCalibPara.planeCalib[0] = 1.0;
groundCalibPara.planeCalib[1] = 0.0;
groundCalibPara.planeCalib[2] = 0.0;
groundCalibPara.planeCalib[3] = 0.0;
groundCalibPara.planeCalib[4] = 1.0;
groundCalibPara.planeCalib[5] = 0.0;
groundCalibPara.planeCalib[6] = 0.0;
groundCalibPara.planeCalib[7] = 0.0;
groundCalibPara.planeCalib[8] = 1.0;
groundCalibPara.planeHeight = -1.0;
for (int i = 0; i < 9; i++)
groundCalibPara.invRMatrix[i] = groundCalibPara.planeCalib[i];
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[grp]);
groundCalibPara = _readCalibPara(calibFile);
double binHeight = 640; //料筐最上边沿距地面高度
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx = 15;
char _scan_file[256];
sprintf_s(_scan_file, "%s隔板%d_LaserData_Jl26C177.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines_XYZ(scanLines);
if (scanLines.size() == 0)
continue;
//地面调平
for (int i = 0; i < (int)scanLines.size(); i++)
{
wd_lineDataR(scanLines[i], groundCalibPara.planeCalib, -1);//调平
for (int j = 0; j < (int)scanLines[i].size(); j++)
scanLines[i][j].nPointIdx = 0;
}
//读取料筐参数
sprintf_s(_scan_file, "%sresult/%d_bin_info.txt", dataPath[grp], fidx);
WD_HRM_BinInfo binInfo = _readBinInfo(_scan_file);
//读取工件参数
sprintf_s(_scan_file, "%sresult/%d_workpiece_info.txt", dataPath[grp], fidx);
WD_HRM_workpieceSizeInfo workpieceInfo = _readWorkpieceInfo(_scan_file);
SSG_size2D realBoardSize; //实际的托板大小
realBoardSize.width = 720.0;
realBoardSize.height = 520.0;
double guardingInterval = 3.0; //工作与工件的保护间隔
long t1 = (long)GetTickCount64();//统计时间
int out_rows = 0, out_cols = 0, isLastLayere = 0;
std::vector< WD_workpieceInfo> planningPositions;
wd_HRM_PlanBinPlacement(
binInfo,
realBoardSize,
workpieceInfo,
groundCalibPara,
guardingInterval, //工作与工件的保护间隔
planningPositions,
&out_rows,
&out_cols,
&isLastLayere);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms), rows=%d cols=%d, isLastLayer=%d...", _scan_file, (int)(t2 - t1), out_rows, out_cols, isLastLayere);
//输出测试结果
sprintf_s(_scan_file, "%sresult/%d_planning_result.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(_scan_file, planningPositions);
//旋转到调平坐标系中
for (int i = 0; i < (int)planningPositions.size(); i++)
{
planningPositions[i].center = wd_ptRotate(planningPositions[i].center, groundCalibPara.planeCalib);
planningPositions[i].x_dir = wd_ptRotate(planningPositions[i].x_dir, groundCalibPara.planeCalib);
planningPositions[i].y_dir = wd_ptRotate(planningPositions[i].y_dir, groundCalibPara.planeCalib);
planningPositions[i].z_dir = wd_ptRotate(planningPositions[i].z_dir, groundCalibPara.planeCalib);
}
sprintf_s(_scan_file, "%sresult/LaserLine%d_planning_result.txt", dataPath[grp], fidx);
_outputRGBDResult_XYZ_RGBD_planningResult(_scan_file, scanLines, binInfo, planningPositions, workpieceInfo.workpieceHeight);
sprintf_s(calibFile, "%sresult/LaserLine%d_planning_result.png", dataPath[grp], fidx);
double rpy[3] = { 0, 0, 0 }; // { -30, 15, 0 }; //{ 0,-45, 0 }; //
double angleDrawLen = 500;
double displayScale = 1.0;
cv::String imgName(calibFile);
_genXOYProjectionImage_planningResult(imgName, scanLines, displayScale, binInfo, planningPositions, rpy, angleDrawLen);
printf("done\n");
}
}
}
typedef enum
{
keSG_2D3D定位_海瑞马_地面调平 = 0,
keSG_2D3D定位_海瑞马_锥形工件,
keSG_2D3D定位_海瑞马_转子芯,
keSG_2D3D定位_海瑞马_码垛料筐定位,
keSG_2D3D定位_海瑞马_码垛工件尺寸测量,
keSG_2D3D定位_海瑞马_码垛位置规划,
} ESG_testMode;
int main()
{
//ESG_testMode testMode = keSG_2D3D定位_海瑞马_地面调平;
//ESG_testMode testMode = keSG_2D3D定位_海瑞马_锥形工件;
ESG_testMode testMode = keSG_2D3D定位_海瑞马_转子芯;
//ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛料筐定位;
//ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛工件尺寸测量;
//ESG_testMode testMode = keSG_2D3D定位_海瑞马_码垛位置规划;
if (keSG_2D3D定位_海瑞马_锥形工件 == testMode)
HaiRuiMa_TaperedWorkpiece_test();
else if (keSG_2D3D定位_海瑞马_地面调平 == testMode)
HaiRuiMa_groundCalib_test();
else if (keSG_2D3D定位_海瑞马_转子芯 == testMode)
HaiRuiMa_rotorCorePositioning_test();
else if (keSG_2D3D定位_海瑞马_码垛料筐定位 == testMode)
HaiRuiMa_BinSizeCompute_test();
else if (keSG_2D3D定位_海瑞马_码垛工件尺寸测量 == testMode)
HaiRuiMa_workpieceSizeCompute_test();
else if (keSG_2D3D定位_海瑞马_码垛位置规划 == testMode)
{
//HaiRuiMa_BinSizeCompute_test();
HaiRuiMa_workpieceSizeCompute_test();
HaiRuiMa_positionPlanning_test();
}
}