workpieceHolePositioning version 1.5.5 : 山东本事机电轮胎定位。(1)添加了轮胎内径大小的输出, (2)按高度排序。最上面的目标排在第一个。

This commit is contained in:
jerryzeng 2026-06-25 16:11:04 +08:00
parent 693471b311
commit 14ba0f0939
6 changed files with 650 additions and 5 deletions

View File

@ -20,6 +20,9 @@ SG_APISHARED_EXPORT float vec3_computeVecAngle(const SVzNL3DPoint& a, const SVzN
SG_APISHARED_EXPORT SVzNL3DPoint wd_ptRotate(SVzNL3DPoint pt3D, const double matrix3d[9]);
//二维点旋转
SG_APISHARED_EXPORT SVzNL2DPointD wd_pt2dRotate(SVzNL2DPointD pt2D_in, double rotateAngle);
//计算总体均值和总体标准差
SG_APISHARED_EXPORT void CalcStats(const std::vector<double>& data, SSG_meanVar& result);
/**
* @brief v n theta
* v 使

View File

@ -463,6 +463,8 @@ typedef struct
bool end_zRising;//终点z上跳标志
}SSG_RUN_EX;
//统计信息:均值和标准差(开根号)
typedef struct
{
double mean;

View File

@ -5,6 +5,7 @@
#include <corecrt_math_defines.h>
#endif // __WIN32
#include <numeric>
#include <cmath>
#include <unordered_map>
#include <Eigen/dense>
@ -89,6 +90,25 @@ SVzNL2DPointD wd_pt2dRotate(SVzNL2DPointD pt2D_in, double rotateAngle)
return result;
}
//计算总体均值和总体标准差
void CalcStats(const std::vector<double>& data, SSG_meanVar& result)
{
size_t n = (int)data.size();
if (n == 0)
return;
double sum = std::accumulate(data.begin(), data.end(), 0.0);
double mean = sum / n;
double sq = 0.0;
for (double v : data) sq += (v - mean) * (v - mean);
sq = sq / n;
result.mean = mean;
result.var = sqrt(sq);
return;
}
/**
* @brief v n theta
* v 使

View File

@ -25,7 +25,8 @@
//version 1.5.2 : 修正工件判断中的一个逻辑错误。
//version 1.5.3 : 添加郑州微力砂轮盘和轮盘架定位API。
//version 1.5.4 : 添加山东本事机电轮胎定位API。
std::string m_strVersion = "HolePostion 1.5.4";
//version 1.5.5 : 山东本事机电轮胎定位。1添加了轮胎内径大小的输出 2按高度排序。最上面的目标排在第一个。
std::string m_strVersion = "HolePostion 1.5.5";
const char* wd_workpieceHolePositioningVersion(void)
{
return m_strVersion.c_str();
@ -2698,6 +2699,10 @@ void _getFlagIntervals_h(
segs.push_back(a_run);
}
bool _compareByTireZValue(WD_HolePositionInfo& a, WD_HolePositionInfo& b)
{
return a.center.z < b.center.z;
}
//山东本事机电轮胎中心定位
void sx_getTireHolePose(
std::vector< std::vector<SVzNL3DPosition>>& scanLinesInput,
@ -3093,10 +3098,13 @@ void _getFlagIntervals_h(
WD_HolePositionInfo a_holeInfo;
a_holeInfo.center = { center.x, center.y, meanZ };
a_holeInfo.normDir = { 0.0, 0.0, 1.0 };
a_holeInfo.holeR = radius;
tirePositions.push_back(a_holeInfo);
}
}
}
//按高度排序
std::sort(tirePositions.begin(), tirePositions.end(), _compareByTireZValue);
if (tirePositions.size() == 0)
{
@ -3113,3 +3121,439 @@ void _getFlagIntervals_h(
return;
}
//模板检查
void _templateChecking(
std::vector<std::vector<double>>& quantiData,
int ref_x, int ref_y,
std::vector<std::vector<int>>& templateMask,
std::vector<double>& circleZ,
std::vector<double>& centerZ)
{
int templateX = (int)templateMask.size();
int templateY = (int)templateMask[0].size();
for (int x = 0; x < templateX; x++)
{
for (int y = 0; y < templateY; y++)
{
if (templateMask[x][y] == 0)
continue;
int maskX = x + ref_x;
int maskY = y + ref_y;
if (quantiData[maskX][maskY] < 1e-4)
continue;
if (templateMask[x][y] == 1)
circleZ.push_back(quantiData[maskX][maskY]);
else if (templateMask[x][y] == 2)
centerZ.push_back(quantiData[maskX][maskY]);
}
}
return;
}
//宁波海瑞马定子芯中心定位
void sx_getRotorCorePose(
std::vector< std::vector<SVzNL3DPosition>>& scanLinesInput,
const SSG_cornerParam cornerPara,
const SSG_planeCalibPara groundCalibPara,
const WD_rotorAppParam rotorParam,
std::vector<WD_HolePositionInfo>& rotorPositions,
int* errCode)
{
*errCode = 0;
//生成数据副本,使用副本数据进行调平和后续处理
int lineNum = (int)scanLinesInput.size();
std::vector< std::vector<SVzNL3DPosition>> scanLines;
scanLines.resize(lineNum);
int linePtNum = (int)scanLinesInput[0].size();
bool isGridData = true;
for (int i = 0; i < lineNum; i++)
{
if (linePtNum != (int)scanLinesInput[i].size())
isGridData = false;
scanLines[i].resize(scanLinesInput[i].size());
std::copy(scanLinesInput[i].begin(), scanLinesInput[i].end(), scanLines[i].begin()); // 使用std::copy算法
for (int j = 0; j < (int)scanLinesInput[i].size(); j++)
scanLinesInput[i][j].nPointIdx = 0; //清零用于debug时记录信息
}
if (false == isGridData)//数据不是网格格式
{
*errCode = SG_ERR_NOT_GRID_FORMAT;
return;
}
//内部参数
double removeGroundHeight = groundCalibPara.planeHeight - rotorParam.removeGroundHOffset;
for (int i = 0; i < lineNum; i++)
{ //行处理
//调平,去除地面
wd_lineDataR(scanLines[i], groundCalibPara.planeCalib, removeGroundHeight);
}
//产生水平扫描数据
std::vector< std::vector<SVzNL3DPosition>> scanLines_h;
scanLines_h.resize(linePtNum);
for (int i = 0; i < linePtNum; i++)
scanLines_h[i].resize(lineNum);
for (int line = 0; line < lineNum; line++)
{
for (int j = 0; j < linePtNum; j++)
{
scanLines[line][j].nPointIdx = 0; //将原始数据的序列清0会转义使用
scanLines_h[j][line] = scanLines[line][j];
scanLines_h[j][line].pt3D.x = scanLines[line][j].pt3D.y;
scanLines_h[j][line].pt3D.y = scanLines[line][j].pt3D.x;
}
}
for (int line = 0; line < linePtNum; line++)
{
for (int j = 0, j_max = (int)scanLines_h[line].size(); j < j_max; j++)
scanLines_h[line][j].nPointIdx = j;
}
//算法流程:
//1、检查垂直方向数据并去除
//2、聚类
//3、保留最前面目标
//4、提取孔
//5、拟合
//6、计算中间坐标
//内部参数
double maxDistTh = 5.0;
double minSegLen = 2.0;
SSG_cornerParam removeVertialPara = cornerPara;
removeVertialPara.scale = 5.0;
removeVertialPara.cornerTh = 60;
std::vector<std::vector<int>> flags;
flags.resize(lineNum);
for (int i = 0; i < lineNum; i++)
{
flags[i].resize(linePtNum);
std::fill(flags[i].begin(), flags[i].end(), 0);
}
std::vector<std::vector<int>> zVertivalFlags;
for (int line = 0; line < lineNum; line++)
{
if (line == 700)
int kkk = 1;
std::vector<int> line_verticalFlags;
wd_getXYVertialFeature_perSeg_dirAngleMethod(
scanLines[line],
line,
maxDistTh,
minSegLen,
removeVertialPara,
line_verticalFlags
);
zVertivalFlags.push_back(line_verticalFlags);
for (int i = 0; i < (int)line_verticalFlags.size(); i++)
{
if (line_verticalFlags[i] > 0)
flags[line][i] = 1;
}
}
std::vector<std::vector<int>> zVertivalFlags_h;
for (int line = 0; line < linePtNum; line++)
{
if (line == 1177)
int kkk = 1;
std::vector<int> line_verticalFlags;
wd_getXYVertialFeature_perSeg_dirAngleMethod(
scanLines[line],
line,
maxDistTh,
minSegLen,
removeVertialPara,
line_verticalFlags
);
zVertivalFlags_h.push_back(line_verticalFlags);
for (int i = 0; i < (int)line_verticalFlags.size(); i++)
{
if (line_verticalFlags[i] > 0)
flags[i][line] = 1;
}
}
for (int line = 0; line < lineNum; line++)
{
for (int j = 0; j < linePtNum; j++)
{
if (flags[line][j] > 0)
{
scanLines[line][j].pt3D.z = 0;
scanLines_h[j][line].pt3D.z = 0;
}
}
}
//迭代一次
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = 5.0;
lineSegPara.segGapTh_y = 5.0;
lineSegPara.segGapTh_z = 5.0;
int minSegSize = 1;
for (int line = 0; line < lineNum; line++)
{
std::vector<SSG_RUN> segs;
wd_getLineDataIntervals(
scanLines[line],
lineSegPara,
segs);
for (int i = 0; i < (int)segs.size(); i++)
{
if (segs[i].len <= minSegSize)
{
int idx0 = segs[i].start;
for (int j = 0; j < segs[i].len; j++)
flags[line][idx0 + j] = 1;
}
}
}
for (int line = 0; line < linePtNum; line++)
{
std::vector<SSG_RUN> segs;
wd_getLineDataIntervals(
scanLines_h[line],
lineSegPara,
segs);
for (int i = 0; i < (int)segs.size(); i++)
{
if (segs[i].len <= minSegSize)
{
int idx0 = segs[i].start;
for (int j = 0; j < segs[i].len; j++)
flags[idx0 + j][line] = 1;
}
}
}
//标注
for (int line = 0; line < lineNum; line++)
{
for (int j = 0; j < linePtNum; j++)
{
scanLinesInput[line][j].nPointIdx = 0; //将原始数据的序列清0会转义使用
scanLines[line][j].nPointIdx = 0;
}
}
//将垂直线段去除
std::vector< SVzNL3DPosition> validPoints;
for (int line = 0; line < lineNum; line++)
{
for (int j = 0; j < linePtNum; j++)
{
if (flags[line][j] > 0)
{
scanLinesInput[line][j].pt3D.z = 0;
scanLines[line][j].pt3D.z = 0;
}
if (scanLines[line][j].pt3D.z > 1e-4)
{
SVzNL3DPosition a_vldPt;
a_vldPt.pt3D = scanLines[line][j].pt3D;
a_vldPt.nPointIdx = (line << 16) | (j & 0xffff);
validPoints.push_back(a_vldPt);
}
}
}
//聚类
int clusterCheckWin = 5;
double clusterDist = 5.0;
int distType = 1; //0 - 2d distance; 1- 3d distance
std::vector<std::vector< SVzNL3DPosition>> objClusters; //result
wd_pointClustering_speedUp(
validPoints,
lineNum, linePtNum, clusterCheckWin, //搜索窗口
clusterDist,
distType,
objClusters //result
);
//保留最前面的目标, 筐子
double minObj_L = rotorParam.basket_L * 0.8;
double maxObj_L = rotorParam.basket_L * 1.25;
double minObj_W = rotorParam.basket_W * 0.8;
double maxObj_W = rotorParam.basket_W * 1.25;
const double topPlateMaxZRange = 100.0;
std::vector<double> objMeanZ;
std::vector<SSG_ROIRectD> objROIs;
std::vector<SVzNLRangeD> objZRange;
objMeanZ.resize(objClusters.size());
objROIs.resize(objClusters.size());
objZRange.resize(objClusters.size());
std::vector<int> validObjIndice;
for (int i = 0; i < (int)objClusters.size(); i++)
{
SSG_ROIRectD a_roi = _getListROI(objClusters[i]);
objROIs[i] = a_roi;
double w = a_roi.right - a_roi.left;
double h = a_roi.bottom - a_roi.top;
double len = w < h ? h : w;
double width = w > h ? h : w;
if ((len > minObj_L) && (width > minObj_W) && (len < maxObj_L) && (width < maxObj_W))
{
SVzNLRangeD zRange;
double meanZ = _getListMeanZ(objClusters[i], zRange);
objMeanZ[i] = meanZ;
objZRange[i] = zRange;
validObjIndice.push_back(i);
}
else
{
objMeanZ[i] = 0;
objZRange[i].max = -1.0;
objZRange[i].min = 0.0;
}
}
if (validObjIndice.size() == 0)
{
*errCode = SG_ERR_ZERO_OBJECTS;
return;
}
//最前面的目标为筐子
int basketClusterIdx = validObjIndice[0];
for (int i = 1; i < (int)validObjIndice.size(); i++)
{
int idx = validObjIndice[i];
if (objMeanZ[basketClusterIdx] > objMeanZ[idx])
basketClusterIdx = idx;
}
std::vector< SVzNL3DPosition>& basketCluster = objClusters[basketClusterIdx];
//提取筐子的四个角点,用于确定目标所在的边
//生成投影图,方便使用模板
const double quantiScale = 1.0; //
SSG_ROIRectD& basketROI = objROIs[basketClusterIdx];
int quantiW = (basketROI.right - basketROI.left) / quantiScale + 1;
if (quantiW % 2 == 1)
quantiW += 1;
int quantiH = (basketROI.bottom - basketROI.top) / quantiScale + 1;
if (quantiH % 2 == 1)
quantiH += 1;
std::vector<std::vector<double>> quantiData;
quantiData.resize(quantiW);
for (int i = 0; i < quantiW; i++)
{
quantiData[i].resize(quantiH);
std::fill(quantiData[i].begin(), quantiData[i].end(), -1);
}
//量化
for (int line = 0; line < lineNum; line++)
{
for (int j = 0; j < linePtNum; j++)
{
if ((scanLines[line][j].pt3D.z > 1e-4) &&
(scanLines[line][j].pt3D.x >= basketROI.left) && (scanLines[line][j].pt3D.x < basketROI.right) &&
(scanLines[line][j].pt3D.y >= basketROI.top) && (scanLines[line][j].pt3D.y < basketROI.bottom))
{
int quantiX = (scanLines[line][j].pt3D.x - basketROI.left) / quantiScale;
int quantiY = (scanLines[line][j].pt3D.y - basketROI.top) / quantiScale;
quantiData[quantiX][quantiY] = scanLines[line][j].pt3D.z;
}
}
}
//生成模板
double template_minR = rotorParam.rotorDiameter - 2.0;
double template_maxR = rotorParam.rotorDiameter + 2.0;
double template_centerR = 10.0;
int template_pixR = (int)(template_maxR / quantiScale + 1);
int template_W = template_pixR * 2 + 1;
double template_cx = (double)template_pixR * quantiScale;
double template_cy = template_cx;
std::vector<std::vector<int>> templateMask;
templateMask.resize(template_W);
for (int i = 0; i < template_W; i++)
templateMask[i].resize(template_W);
for (int i = 0; i < template_W; i++)
{
for (int j = 0; j < template_W; j++)
{
double x = (double)i * quantiScale;
double y = (double)j * quantiScale;
double dist = sqrt(pow(x - template_cx, 2) + pow(y - template_cy, 2));
if ((dist >= template_minR) && (dist <= template_maxR))
templateMask[i][j] = 1;
else if (dist <= template_centerR)
templateMask[i][j] = 2;
}
}
if ((template_W >= quantiW) || (template_W >= quantiH))
{
*errCode = SG_ERR_ZERO_OBJECTS;
return;
}
//搜索目标
std::vector<std::vector<SSG_meanVar>> statsCircle;
std::vector<std::vector<SSG_meanVar>> statsCenter;
statsCircle.resize(quantiW);
statsCenter.resize(quantiW);
for (int i = 0; i < quantiW; i++)
{
statsCircle[i].resize(quantiH);
statsCenter[i].resize(quantiH);
}
int searchStart_X = template_pixR;
int searchEnd_X = quantiW - 1 - template_pixR;
int searchStart_Y = template_pixR;
int searchEnd_Y = quantiH - 1 - template_pixR;
for (int x = searchStart_X; x < searchEnd_X; x++)
{
for (int y = searchStart_Y; y < searchEnd_Y; y++)
{
std::vector<double> circleZ;
std::vector<double> centerZ;
//模板检查
_templateChecking(
quantiData,
x - template_pixR, y - template_pixR,
templateMask,
circleZ,
centerZ);
//计算均值和方差
SSG_meanVar satasInfo_circle = { 0.0, 0.0 };
CalcStats(circleZ, satasInfo_circle);
statsCircle[x][y] = satasInfo_circle;
SSG_meanVar satasInfo_center = { 0.0, 0.0 };
CalcStats(centerZ, satasInfo_center);
statsCenter[x][y] = satasInfo_center;
}
}
//搜索方差极小值点, circle和center的方差累加后的极小值
//两步搜索法先搜索5x5的再搜索模块大小
std::vector< SSG_2DValueI> varPeaks_5x5;
for (int i = 0; i < template_W; i++)
{
for (int j = 0; j < template_W; j++)
{
}
}
//旋转回原坐标系
for (int i = 0; i < (int)rotorPositions.size(); i++)
{
rotorPositions[i].center = _ptRotate(rotorPositions[i].center, groundCalibPara.invRMatrix);
rotorPositions[i].normDir = _ptRotate(rotorPositions[i].normDir, groundCalibPara.invRMatrix);
}
return;
}

View File

@ -37,8 +37,17 @@ typedef struct
{
SVzNL3DPoint center;
SVzNL3DPoint normDir; //方向向量(归一化)
double holeR;
}WD_HolePositionInfo;
typedef struct
{
double rotorDiameter;
double removeGroundHOffset; //去除时的高度偏置,用于设置架子高度
double basket_L; //零件筐-长
double basket_W; //零件筐-宽
}WD_rotorAppParam;
//读版本号
SG_APISHARED_EXPORT const char* wd_workpieceHolePositioningVersion(void);
@ -94,3 +103,12 @@ SG_APISHARED_EXPORT void sx_getTireHolePose(
const WD_tireParam tireParam,
std::vector<WD_HolePositionInfo>& tirePositions,
int* errCode);
//宁波海瑞马定子芯中心定位
SG_APISHARED_EXPORT void sx_getRotorCorePose(
std::vector< std::vector<SVzNL3DPosition>>& scanLinesInput,
const SSG_cornerParam cornerPara,
const SSG_planeCalibPara groundCalibPara,
const WD_rotorAppParam rotorParam,
std::vector<WD_HolePositionInfo>& rotorPositions,
int* errCode);

View File

@ -172,7 +172,7 @@ void _outputHoleInfo(char* fileName, std::vector< WD_HolePositionInfo>& holePosi
int number = (int)holePositioning.size();
for (int i = 0; i < number; i++)
{
sprintf_s(dataStr, 250, "孔_%d", i + 1);
sprintf_s(dataStr, 250, "孔_%d: R=%g", i + 1, holePositioning[i].holeR);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " center: (%g, %g, %g)", holePositioning[i].center.x, holePositioning[i].center.y, holePositioning[i].center.z);
sw << dataStr << std::endl;
@ -673,7 +673,10 @@ void _outputRGBDResult_HoleInfo(
size = 10;
for (int i = 0; i < linePtNum; i++)
{
rgb = {255, 0, 0};
if (i == 0)
rgb = { 255,255,0 };
else
rgb = {0, 0, 255};
float x = (float)objects[i].pt3D.x;
float y = (float)objects[i].pt3D.y;
float z = (float)objects[i].pt3D.z;
@ -1436,6 +1439,7 @@ void Benshi_tirePosition_test(void)
#endif
}
typedef enum
{
keSG_拓普发孔定位 = 0,
@ -1443,8 +1447,159 @@ typedef enum
keSG_微力砂轮盘定位,
keSG_微力砂轮架子定位,
keSG_山东本事轮胎定位,
keSG_宁波海瑞马转子芯定位,
} ESG_testMode;
//山东本事机电轮胎定位
#define HAIRUIMA_COMPUTE_CALIB_PARA 0
#define HAIRUIMA_HOLE_POSITION 1
#define HAIRUIMA_TIRE_TEST_GROUP 1
void HaiRuiMa_rotorCorePosition_test(void)
{
const char* dataPath[BENSHI_TIRE_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/宁波海瑞马/转子钢芯/数据/", //0
};
SVzNLRange fileIdx[BENSHI_TIRE_TEST_GROUP] = {
{1,83},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if HAIRUIMA_COMPUTE_CALIB_PARA
int cvtGrp = 0;
char _calib_datafile[256];
sprintf_s(_calib_datafile, "%s地面点云.txt", dataPath[cvtGrp]);
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)
{
SSG_planeCalibPara calibPara = wd_getGroundCalibPara(scanData);
//结果进行验证
for (int i = 0; i < lineNum; i++)
{
if (i == 14)
int kkk = 1;
//行处理
//调平,去除地面
wd_lineDataR(scanData[i], calibPara.planeCalib, -1);
}
//
char calibFile[250];
sprintf_s(calibFile, "%sground_calib_para.txt", dataPath[cvtGrp]);
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "%sscanData_ground_calib_verify.txt", dataPath[cvtGrp]);
int headNullLines = 0;
_outputScanDataFile_vector(_out_file, scanData, false, &headNullLines);
#if 0
for (int fidx = fileIdx[cvtGrp].nMin; fidx <= fileIdx[cvtGrp].nMax; fidx++)
{
//fidx =4;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jl26C477.txt", dataPath[cvtGrp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
if (scanLines.size() == 0)
continue;
lineNum = (int)scanLines.size();
for (int i = 0; i < lineNum; i++)
{
//调平,去除地面
wd_lineDataR(scanLines[i], calibPara.planeCalib, -1);
}
printf("%s: processing...\n", _scan_file);
sprintf_s(_scan_file, "%sLaserData_%d_calib_verify.txt", dataPath[cvtGrp], fidx);
int headNullLines = 0;
_outputScanDataFile_vector(_scan_file, scanLines, false, &headNullLines);
}
#endif
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if HAIRUIMA_HOLE_POSITION
for (int grp = 0; grp <= 0; 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 =17;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jl26C477.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
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_rotorAppParam rotorParam;
rotorParam.rotorDiameter = 76;
rotorParam.removeGroundHOffset = 100.0; //去除时的高度偏置,用于设置架子高度
rotorParam.basket_L = 770;
rotorParam.basket_W = 580;
int errCode = 0;
std::vector<WD_HolePositionInfo> rotorPositions;
sx_getRotorCorePose(
scanLines,
cornerParam,
groundCalibPara,
rotorParam,
rotorPositions,
&errCode);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
//输出测试结果
double dirLen = 200;
sprintf_s(_scan_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_HoleInfo(_scan_file, scanLines, rotorPositions, dirLen);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo(_scan_file, rotorPositions);
}
}
#endif
}
int main()
{
//ESG_testMode testMode = keSG_拓普发孔定位;
@ -1452,6 +1607,7 @@ int main()
//ESG_testMode testMode = keSG_微力砂轮盘定位;
//ESG_testMode testMode = keSG_微力砂轮架子定位;
ESG_testMode testMode = keSG_山东本事轮胎定位;
//ESG_testMode testMode = keSG_宁波海瑞马转子芯定位;
if (keSG_拓普发孔定位 == testMode)
TuoPuFa_holePosition_test();
@ -1463,4 +1619,6 @@ int main()
Weili_grindingDiscRackPosition_test();
else if (keSG_山东本事轮胎定位 == testMode)
Benshi_tirePosition_test();
else if (keSG_宁波海瑞马转子芯定位 == testMode)
HaiRuiMa_rotorCorePosition_test();
}