GrabBag/AppAlgo/workpieceHolePositioning/workpieceHolePositioning_test.cpp

2758 lines
92 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.

// BQ_workpieceCornerExtract_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <VZNL_Types.h>
#include "direct.h"
#include <string>
#include "workpieceHolePositioning_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;
}
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(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;
}
void _removeZeroLines(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(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 _outputScanDataFile_XYZ_vector(char* fileName, std::vector<std::vector< SVzNL3DPosition>>& scanData)
{
std::ofstream sw(fileName);
int lineNum = scanData.size();
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;
for (int line = 0; line < lineNum; line++)
{
int nPositionCnt = scanData[line].size();
sw << "Line_" << line << "_0_" << nPositionCnt << std::endl;
for (int i = 0; i < nPositionCnt; i++)
{
SVzNL3DPosition* pt3D = &scanData[line][i];
float x = (float)pt3D->pt3D.x;
float y = (float)pt3D->pt3D.y;
float z = (float)pt3D->pt3D.z;
char str[250];
sprintf_s(str, "{ %f, %f, %f } - { 0, 0 } - { 0, 0 }", x, y, z);
sw << str << std::endl;
}
}
sw.close();
}
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();
}
void _outputWorkpieceInfo(char* fileName, std::vector< WD_workpieceInfo>& workpiecePositioning)
{
std::ofstream sw(fileName);
char dataStr[250];
int number = (int)workpiecePositioning.size();
for (int i = 0; i < number; i++)
{
sprintf_s(dataStr, 250, "工件_%d", i + 1);
sw << dataStr << std::endl;
int holeNumber = (int)workpiecePositioning[i].holes.size();
for (int j = 0; j < holeNumber; j++)
{
sprintf_s(dataStr, 250, " 孔%d: (%g, %g, %g)", (j+1), workpiecePositioning[i].holes[j].x, workpiecePositioning[i].holes[j].y, workpiecePositioning[i].holes[j].z);
sw << dataStr << std::endl;
}
sprintf_s(dataStr, 50, " center: (%g, %g, %g)", workpiecePositioning[i].center.x, workpiecePositioning[i].center.y, workpiecePositioning[i].center.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " x_dir: (%g, %g, %g)", workpiecePositioning[i].x_dir.x, workpiecePositioning[i].x_dir.y, workpiecePositioning[i].x_dir.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " y_dir: (%g, %g, %g)", workpiecePositioning[i].y_dir.x, workpiecePositioning[i].y_dir.y, workpiecePositioning[i].y_dir.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 50, " z_dir: (%g, %g, %g)", workpiecePositioning[i].z_dir.x, workpiecePositioning[i].z_dir.y, workpiecePositioning[i].z_dir.z);
sw << dataStr << std::endl;
}
sw.close();
}
void _outputHoleInfo(char* fileName, std::vector< WD_HolePositionInfo>& holePositioning)
{
std::ofstream sw(fileName);
char dataStr[250];
int number = (int)holePositioning.size();
for (int i = 0; i < number; i++)
{
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;
sprintf_s(dataStr, 250, " norm_dir: (%g, %g, %g)", holePositioning[i].normDir.x, holePositioning[i].normDir.y, holePositioning[i].normDir.z);
sw << dataStr << std::endl;
}
sw.close();
}
void _outputHoleInfo_2(char* fileName, const WD_HolePositionInfo holePose)
{
std::ofstream sw(fileName);
char dataStr[250];
sprintf_s(dataStr, 250, "孔_1");
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " center: (%g, %g, %g)", holePose.center.x, holePose.center.y, holePose.center.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " norm_dir: (%g, %g, %g)", holePose.normDir.x, holePose.normDir.y, holePose.normDir.z);
sw << dataStr << std::endl;
sw.close();
}
void _outputHoleInfo_3(char* fileName, const SSG_pointPose holePose)
{
std::ofstream sw(fileName);
char dataStr[250];
sprintf_s(dataStr, 250, "孔_1");
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " center: (%g, %g, %g)", holePose.point.x, holePose.point.y, holePose.point.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " x_dir: (%g, %g, %g)", holePose.pose_x.x, holePose.pose_x.y, holePose.pose_x.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " y_dir: (%g, %g, %g)", holePose.pose_y.x, holePose.pose_y.y, holePose.pose_y.z);
sw << dataStr << std::endl;
sprintf_s(dataStr, 250, " norm_dir: (%g, %g, %g)", holePose.pose_z.x, holePose.pose_z.y, holePose.pose_z.z);
sw << dataStr << std::endl;
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();
}
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 _outputRGBDResult_RGBD(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
std::vector< WD_workpieceInfo>& workpiecePositioning)
{
std::vector<SVzNL3DPosition> objects;
int objNumber = (int)workpiecePositioning.size();
for (int i = 0; i < objNumber; i++)
{
SVzNL3DPosition a_objPt;
a_objPt.pt3D = workpiecePositioning[i].center;
objects.push_back(a_objPt);
int holeNumber = (int)workpiecePositioning[i].holes.size();
for (int j = 0; j < holeNumber; j++)
{
a_objPt.nPointIdx = i + 1;
a_objPt.pt3D = workpiecePositioning[i].holes[j];
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++)
{
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;
}
}
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 = 5;
rgb = { 255, 0, 0 };
}
else
{
rgb = { 255, 255, 0 };
size = 5;
}
//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++)
{
SVzNL3DPoint dirPt;
dirPt = { workpiecePositioning[i].center.x + workpiecePositioning[i].y_dir.x * 10,
workpiecePositioning[i].center.y + workpiecePositioning[i].y_dir.y * 10,
workpiecePositioning[i].center.z + workpiecePositioning[i].y_dir.z * 10 };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << workpiecePositioning[i].center.x << "," << workpiecePositioning[i].center.y << "," << workpiecePositioning[i].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt.x << "," << dirPt.y << "," << dirPt.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
dirPt = { workpiecePositioning[i].center.x + workpiecePositioning[i].z_dir.x * 10,
workpiecePositioning[i].center.y + workpiecePositioning[i].z_dir.y * 10,
workpiecePositioning[i].center.z + workpiecePositioning[i].z_dir.z * 10 };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << workpiecePositioning[i].center.x << "," << workpiecePositioning[i].center.y << "," << workpiecePositioning[i].center.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << 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++;
for (int j = 0; j < (int)workpiecePositioning[i].holes.size(); j++)
{
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << workpiecePositioning[i].holes[j].x << "," << workpiecePositioning[i].holes[j].y << "," << workpiecePositioning[i].holes[j].z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << workpiecePositioning[i].holesDir[j].x << "," << workpiecePositioning[i].holesDir[j].y << "," << workpiecePositioning[i].holesDir[j].z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
}
sw.close();
}
void _outputRGBDResult_RGBD_2(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
SSG_pointPose& poseInfo)
{
int objNumber = 0;
if (poseInfo.point.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.point.z > 1e-4)
{
sw << "Line_" << lineNum << "_0_1" << std::endl;
lineNum++;
size = 20;
rgb = { 255, 255, 0 };
float x = (float)poseInfo.point.x;
float y = (float)poseInfo.point.y;
float z = (float)poseInfo.point.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 = 250;
SVzNL3DPoint dirPt;
dirPt = { poseInfo.point.x + poseInfo.pose_x.x * dirLen,
poseInfo.point.y + poseInfo.pose_x.y * dirLen,
poseInfo.point.z + poseInfo.pose_x.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << poseInfo.point.x << "," << poseInfo.point.y << "," << poseInfo.point.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, 250, 0 };
dirPt = { poseInfo.point.x + poseInfo.pose_y.x * dirLen,
poseInfo.point.y + poseInfo.pose_y.y * dirLen,
poseInfo.point.z + poseInfo.pose_y.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << poseInfo.point.x << "," << poseInfo.point.y << "," << poseInfo.point.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 };
SVzNL3DPoint dirPt1 = { poseInfo.point.x + poseInfo.pose_z.x * dirLen,
poseInfo.point.y + poseInfo.pose_z.y * dirLen,
poseInfo.point.z + poseInfo.pose_z.z * dirLen };
SVzNL3DPoint dirPt2 = { poseInfo.point.x - poseInfo.pose_z.x * dirLen,
poseInfo.point.y - poseInfo.pose_z.y * dirLen,
poseInfo.point.z - poseInfo.pose_z.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++;
}
sw.close();
}
void _outputRGBDResult_HoleInfo(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
std::vector< WD_HolePositionInfo>& holePositioning,
const double dirLen)
{
std::vector<SVzNL3DPosition> objects;
int objNumber = (int)holePositioning.size();
for (int i = 0; i < objNumber; i++)
{
SVzNL3DPosition a_objPt;
a_objPt.pt3D = holePositioning[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;
std::vector< SVzNL3DPosition> vlPts;
for (int i = 0; i < linePtNum; i++)
{
if (scanLines[line][i].pt3D.z > 1e-4)
vlPts.push_back(scanLines[line][i]);
}
linePtNum = (int)vlPts.size();
if (linePtNum == 0)
continue;
sw << "Line_" << lineIdx << "_0_" << linePtNum << std::endl;
lineIdx++;
for (int i = 0; i < linePtNum; i++)
{
SVzNL3DPosition* pt3D = &vlPts[i];
if (pt3D->nPointIdx > 0)
int kkk = 1;
int flag = pt3D->nPointIdx & 0xffff;
if (flag == 2)
{
rgb = { 0, 0, 200 };
size = 2;
}
else if (flag > 2)
{
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;
}
}
int linePtNum = (int)objects.size();
sw << "Line_" << lineNum << "_0_" << linePtNum + 1 << std::endl;
lineNum++;
size = 10;
for (int i = 0; i < linePtNum; i++)
{
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;
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++)
{
SVzNL3DPoint dirPt_1, dirPt_2;
dirPt_1 = { holePositioning[i].center.x - holePositioning[i].normDir.x * dirLen,
holePositioning[i].center.y - holePositioning[i].normDir.y * dirLen,
holePositioning[i].center.z - holePositioning[i].normDir.z * dirLen };
dirPt_2 = { holePositioning[i].center.x + holePositioning[i].normDir.x * dirLen,
holePositioning[i].center.y + holePositioning[i].normDir.y * dirLen,
holePositioning[i].center.z + holePositioning[i].normDir.z * dirLen };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt_1.x << "," << dirPt_1.y << "," << dirPt_1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt_2.x << "," << dirPt_2.y << "," << dirPt_2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
sw.close();
}
void _outputRGBDResult_HoleInfo_2(
char* fileName,
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
WD_HolePositionInfo& holePose)
{
int objNumber = 0;
if (holePose.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 (objNumber > 0)
{
sw << "Line_" << lineNum << "_0_1" << std::endl;
lineNum++;
size = 10;
rgb = { 255, 0, 0 };
float x = (float)holePose.center.x;
float y = (float)holePose.center.y;
float z = (float)holePose.center.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;
SVzNL3DPoint dirPt_1, dirPt_2;
dirPt_1 = { holePose.center.x - holePose.normDir.x * 100,
holePose.center.y - holePose.normDir.y * 100,
holePose.center.z - holePose.normDir.z * 100 };
dirPt_2 = { holePose.center.x + holePose.normDir.x * 100,
holePose.center.y + holePose.normDir.y * 100,
holePose.center.z + holePose.normDir.z * 100 };
sw << "Poly_" << lineIdx << "_2" << std::endl;
sw << "{" << dirPt_1.x << "," << dirPt_1.y << "," << dirPt_1.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
sw << "{" << dirPt_2.x << "," << dirPt_2.y << "," << dirPt_2.z << "}-";
sw << "{0,0}-{0,0}-";
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
lineIdx++;
}
sw.close();
}
SVzNL3DPoint _pointRT(SVzNL3DPoint& origin, const double* R, const double* T)
{
SVzNL3DPoint result;
result.x = origin.x * R[0] + origin.y * R[1] + origin.z * R[2];
result.y = origin.x * R[3] + origin.y * R[4] + origin.z * R[5];
result.z = origin.x * R[6] + origin.y * R[7] + origin.z * R[8];
result.x += T[0];
result.y += T[1];
result.z += T[2];
return result;
}
void _XOYprojection(
cv::Mat& img,
std::vector<std::vector< SVzNL3DPosition>>& 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< 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 (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);
for (int m = 0; m < (int)a_hole.holes.size(); m++)
{
px = (int)((a_hole.holes[m].x - x_range.min) / scale + sideWidth);
py = (int)((a_hole.holes[m].y - y_range.min) / scale + sideWidth);
cv::circle(img, cv::Point(px, py), size, cv::Scalar(rgb[2], rgb[1], rgb[0]), -1);
}
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(
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 _genXOYProjectionImage(
cv::String& fileName,
std::vector<std::vector< SVzNL3DPosition>>& 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());
for (int i = 0; i < (int)holes.size(); i++)
{
r_objOps[i].workpieceType = holes[i].workpieceType;
r_objOps[i].center = _ptRotate(holes[i].center, matrix3d);
r_objOps[i].x_dir = _ptRotate(holes[i].x_dir, matrix3d);
r_objOps[i].y_dir = _ptRotate(holes[i].y_dir, matrix3d);
r_objOps[i].z_dir = _ptRotate(holes[i].z_dir, matrix3d);
for (int m = 0; m < (int)holes[i].holes.size(); m++)
{
SVzNL3DPoint r_pt = _ptRotate(holes[i].holes[m], matrix3d);
r_objOps[i].holes.push_back(r_pt);
}
for (int m = 0; m < (int)holes[i].holesDir.size(); m++)
{
SVzNL3DPoint r_pt = _ptRotate(holes[i].holesDir[m], matrix3d);
r_objOps[i].holesDir.push_back(r_pt);
}
}
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 = 4;
int imgCols = x_cols + sideWidth * 2;
int imgRows = y_rows + sideWidth * 2;
cv::Mat img = cv::Mat::zeros(imgRows, imgCols, CV_8UC3);
//计算投影比例
_XOYprojection(img, rotateLines, r_objOps, scale, sideWidth, rx_range, ry_range, true, dirLen);
cv::imwrite(fileName, img);
return;
}
#define TEST_COMPUTE_CALIB_PARA 0
#define TEST_COMPUTE_HOLE 1
#define TEST_COMPUTE_RT 0
#define TPF_TEST_GROUP 3
//拓普发工件孔定位(工件定位)
void TuoPuFa_holePosition_test(void)
{
const char* dataPath[TPF_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/拓普发点云/", //0
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/拓普发点云2/", //1
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/拓普发点云3/", //2
};
SVzNLRange fileIdx[TPF_TEST_GROUP] = {
{6,6}, {1, 16}, {1,19}
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_RT
std::vector<cv::Point3d> pts_eye;
pts_eye.resize(6);
std::vector<cv::Point3d> pts_robot;
pts_robot.resize(6);
pts_eye[0] = { 463.48, 347.63, 1301.43 }; //, R = 0.6413, P = 0.0302, Y = -91.1494
pts_eye[1] = { 254.15, 259.55, 1303.12 }; // R = 0.6413, P = 0.0302, Y = -88.8130
pts_eye[2] = { 141.16, 284.02, 1302.27 }; //, R = 0.6413, P = 0.0302, Y = -89.3432
pts_eye[3] = { 90.66, 5.80, 1303.27 }; // R = 0.6413, P = 0.0302, Y = -89.5285
pts_eye[4] = { 252.47, -10.45, 1304.33 };// R = 0.6413, P = 0.0302, Y = -89.6450
pts_eye[5] = { 403.53, -13.99, 1304.24 };// R = 0.6413, P = 0.0302, Y = -82.0278
//pts_eye[6] = { 242.70, -74.51, 1796.83 };
//A:绕z, B绕y C:绕x
pts_robot[0] = { -406.649, -1246.187, 588.611 }; // A:0.018 B : -0.638 C : -0.292
pts_robot[1] = { -316.649, -1036.290, 587.619 }; // A:-1.032 B : -0.354 C : 1.001
pts_robot[2] = { -340.590, -922.510, 586.731 }; // A:-1.032 B : -0.356 C : 0.998
pts_robot[3] = { -61.892,-874.564,589.841 }; // A:-1.028 B : -0.367 C : 0.442
pts_robot[4] = { -46.658,-1036.959,589.820 }; // A:-1.029 B : -0.367 C : 0.442
pts_robot[5] = { -43.92, -1188.370,591.006 }; // A:-9.208 B : -0.367 C : 0.442
//pts_robot[6] = { 29.298, -1033.69, 97.909 };
//使用前6组数据
std::vector<cv::Point3d> test_pts_eye;
std::vector<cv::Point3d> test_pts_robot;
for (int i = 0; i < 6; i++)
{
test_pts_eye.push_back(pts_eye[i]);
test_pts_robot.push_back(pts_robot[i]);
}
//对空间两组对应点计算旋转平移矩阵
// Eigen库实现
cv::Mat R, T;
cv::Point3d C_eye, C_robot;
caculateRT(
test_pts_eye,
test_pts_robot,
R, T,
C_eye, C_robot);
std::cout << "方向向量转换结果:" << std::endl;
std::cout << std::fixed << std::setprecision(6); // 固定小数位数为6
std::cout << R << std::endl;
std::cout << T << std::endl;
//验算6轴姿态
std::vector<cv::Point3d> verify_pts_eye;
verify_pts_eye.insert(verify_pts_eye.end(), pts_eye.begin(), pts_eye.begin()+6);
//cv::Point3d a_center = { 232.997, -173.533, 1795.9 };
//verify_pts_eye.push_back(a_center);
//a_center = { 225.57, -68.33, 1796.77 };
//verify_pts_eye.push_back(a_center);
//a_center = { 120.45, -45.97, 1796.25 };
//verify_pts_eye.push_back(a_center);
//a_center = { 242.70, -74.51, 1796.83 };
//verify_pts_eye.push_back(a_center);
std::vector<std::vector< cv::Point3d>> pose_eye;
pose_eye.resize(6);
for (int i = 0; i < 6; i++)
pose_eye[i].resize(3);
pose_eye[0][0] = { -0.046,-0.999,-0.009 }; pose_eye[0][1] = { 0.999,-0.046,0.004 }; pose_eye[0][2] = { -0.005,-0.009,1.000 };
pose_eye[1][0] = { -0.049,-0.999,-0.009 }; pose_eye[1][1] = { 0.999,-0.050,0.004 }; pose_eye[1][2] = { -0.005,-0.009,1.000 };
pose_eye[2][0] = { -0.049,-0.999,-0.009 }; pose_eye[2][1] = { 0.999,-0.049,0.004 }; pose_eye[2][2] = { -0.005,-0.009,1.000 };
pose_eye[3][0] = { -0.059,-0.998,-0.009 }; pose_eye[3][1] = { 0.998,-0.059,0.004 }; pose_eye[3][2] = { -0.005,-0.009,1.000 };
pose_eye[4][0] = { -0.070,-0.997,-0.009 }; pose_eye[4][1] = { 0.998,-0.070,0.004 }; pose_eye[4][2] = { -0.005,-0.009,1.000 };
pose_eye[5][0] = { -0.068,-0.998,-0.009 }; pose_eye[5][1] = { 0.998,-0.068,0.004 }; pose_eye[5][2] = { -0.005,-0.009,1.000 };
//pose_eye[6][0] = { 0.136746, -0.990563, -0.00926168 }; pose_eye[6][1] = { 0.990606, 0.136747, 0.000517805 }; pose_eye[6][2] = { 0.000753588, -0.00924548, 0.999957 };
//pose_eye[7][0] = { 0.058, 0.998, 0.011 }; pose_eye[7][1] = { 0.999, -0.046, 0.003 }; pose_eye[7][2] = { 0.003, 0.011, -1.000 };
//pose_eye[8][0] = { 0.017,1.000,0.011 }; pose_eye[8][1] = { 1.000,-0.008,0.003 }; pose_eye[8][2] = { 0.003,0.011,-1.000 };
//pose_eye[9][0] = { -0.316, 0.949, 0.009 }; pose_eye[9][1] = { 0.951, 0.310, 0.007 }; pose_eye[9][2] = { 0.003, 0.011, -1.000 };
for (int i = 0; i < 6; i++)
{
cv::Point3d rtPt;
pointRT_2(R, T, verify_pts_eye[i], rtPt); //RT前后的点
std::vector<cv::Point3d> dirVectors_eye = pose_eye[i];
//dirVectors_eye[0] = { -dirVectors_eye[0].x, -dirVectors_eye[0].y, -dirVectors_eye[0].z };
dirVectors_eye[1] = { -dirVectors_eye[1].x, -dirVectors_eye[1].y, -dirVectors_eye[1].z };
dirVectors_eye[2] = { -dirVectors_eye[2].x, -dirVectors_eye[2].y, -dirVectors_eye[2].z };
std::vector<cv::Point3d> dirVectors_robot;
for (int j = 0; j < 3; j++)
{
cv::Point3d rt_pt;
pointRotate(R, dirVectors_eye[j], rt_pt);
dirVectors_robot.push_back(rt_pt);
}
//生成旋转矩阵
double R_pose[3][3];
R_pose[0][0] = dirVectors_robot[0].x;
R_pose[0][1] = dirVectors_robot[1].x;
R_pose[0][2] = dirVectors_robot[2].x;
R_pose[1][0] = dirVectors_robot[0].y;
R_pose[1][1] = dirVectors_robot[1].y;
R_pose[1][2] = dirVectors_robot[2].y;
R_pose[2][0] = dirVectors_robot[0].z;
R_pose[2][1] = dirVectors_robot[1].z;
R_pose[2][2] = dirVectors_robot[2].z;
SSG_EulerAngles test_rpy = rotationMatrixToEulerZYX(R_pose);
std::cout << i << ":" << std::endl;
std::cout << rtPt.x << "," << rtPt.y << "," << rtPt.z << std::endl;
std::cout << test_rpy.roll << "," << test_rpy.pitch << "," << test_rpy.yaw << std::endl;
}
#endif
#if TEST_COMPUTE_CALIB_PARA
int cvtGrp = 1;
char _calib_datafile[256];
sprintf_s(_calib_datafile, "%s1470mm调平.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 1
for (int fidx = fileIdx[cvtGrp].nMin; fidx <= fileIdx[cvtGrp].nMax; fidx++)
{
//fidx =4;
char _scan_file[256];
sprintf_s(_scan_file, "%sLaserData_%d.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);
}
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 TEST_COMPUTE_HOLE
for (int grp = 1; grp <= 2; 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 =4;
char _scan_file[256];
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = 10.0;
lineSegPara.segGapTh_y = 15.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 2.0; //mm
growParam.minVTypeTreeLen = 2.0; //mm
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 6.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 47;
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositioning;
wd_workpieceHolePositioning(
scanLines,
workpiecePara,
lineSegPara,
filterParam,
growParam,
groundCalibPara,
workpiecePositioning,
&errCode);
long t2 = (long)GetTickCount64();
if(errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留! ...", _scan_file, (int)(t2 - t1));
else if(errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品! ...", _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_RGBD(_scan_file, scanLines, workpiecePositioning);
sprintf_s(calibFile, "%sresult/LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositioning);
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, workpiecePositioning, rpy, angleDrawLen);
printf("done\n");
}
}
#endif
}
#define TPF2_TEST_GROUP 10
//拓普发工件孔定位(工件定位)
void TuoPuFa_holePosition_test2(void)
{
const char* dataPath[TPF2_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/1层/", //0
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/2层/", //1
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/3层/", //2
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/4层/", //3
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/5层/", //4
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/6层/", //5
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/7层/", //6
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/8层/", //7
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/9层/", //8
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/10层/", //9
};
SVzNLRange fileIdx[TPF2_TEST_GROUP] = {
{1,10}, {1, 11}, {1,10}, {1,10}, {1, 11},
{1,10}, {1, 10}, {1,11}, {1,10}, {1,10}
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_CALIB_PARA
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/调平数据.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)
{
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, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/scanData_ground_calib_verify.txt");
int headNullLines = 0;
_outputScanDataFile_vector(_out_file, scanData, false, &headNullLines);
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if TEST_COMPUTE_HOLE
for (int grp = 0; grp < TPF2_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 =2;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B074.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = 10.0;
lineSegPara.segGapTh_y = 15.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 2.0; //mm
growParam.minVTypeTreeLen = 2.0; //mm
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 8.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 47;
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositioning;
wd_workpieceHolePositioning_2(
scanLines,
workpiecePara,
lineSegPara,
filterParam,
growParam,
groundCalibPara,
workpiecePositioning,
&errCode);
long t2 = (long)GetTickCount64();
if (errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留! ...", _scan_file, (int)(t2 - t1));
else if (errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品! ...", _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_RGBD(_scan_file, scanLines, workpiecePositioning);
sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositioning);
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, workpiecePositioning, rpy, angleDrawLen);
printf("done\n");
}
}
#endif
}
#define TPF3_TEST_GROUP 7
//拓普发工件孔定位(工件定位)
void TuoPuFa_holePosition_test3(void)
{
const char* dataPath[TPF3_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/1层/", //0
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/2层/", //1
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/3层/", //2
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/4层/", //3
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/5层/", //4
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/6层/", //5
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件3/7层/", //6
};
SVzNLRange fileIdx[TPF3_TEST_GROUP] = {
{1,10}, {1, 10}, {1,10}, {1,10}, {1, 10},
{1,10}, {1, 10},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_CALIB_PARA
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/调平数据.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)
{
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, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/scanData_ground_calib_verify.txt");
int headNullLines = 0;
_outputScanDataFile_vector(_out_file, scanData, false, &headNullLines);
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if TEST_COMPUTE_HOLE
for (int grp = 0; grp < TPF3_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 = 2;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B074.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 2.0; //mm
growParam.minVTypeTreeLen = 2.0; //mm
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 6.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 60;
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = workpiecePara.H * 0.5; //此参数用作判断工件孔点是否在同一个工件上
lineSegPara.segGapTh_y = 40.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
double bigHoleDiameter = 33.0;
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositioning;
wd_workpieceHolePositioning_3(
scanLines,
workpiecePara,
bigHoleDiameter,
lineSegPara,
filterParam,
growParam,
groundCalibPara,
workpiecePositioning,
&errCode);
long t2 = (long)GetTickCount64();
if (errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留! ...", _scan_file, (int)(t2 - t1));
else if (errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品! ...", _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_RGBD(_scan_file, scanLines, workpiecePositioning);
sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositioning);
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, workpiecePositioning, rpy, angleDrawLen);
printf("done\n");
}
}
#endif
}
#define TPF4_TEST_GROUP 7
//拓普发工件孔定位(工件定位)
void TuoPuFa_holePosition_test4(void)
{
const char* dataPath[TPF4_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/1层/", //0
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/2层/", //1
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/3层/", //2
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/4层/", //3
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/5层/", //4
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/6层/", //5
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件4/7层/", //6
};
SVzNLRange fileIdx[TPF4_TEST_GROUP] = {
{1,11}, {1, 11}, {1,11}, {1,10}, {1, 10},
{1,10}, {1, 10},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_CALIB_PARA
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/调平数据.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)
{
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, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/scanData_ground_calib_verify.txt");
int headNullLines = 0;
_outputScanDataFile_vector(_out_file, scanData, false, &headNullLines);
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if TEST_COMPUTE_HOLE
for (int grp = 0; grp < TPF4_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 = 2;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B074.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 2.0; //mm
growParam.minVTypeTreeLen = 2.0; //mm
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 6.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 60;
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = workpiecePara.H * 0.5; //此参数用作判断工件孔点是否在同一个工件上
lineSegPara.segGapTh_y = 40.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
double bigHoleDiameter = 33.0;
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositioning;
wd_workpieceHolePositioning_3(
scanLines,
workpiecePara,
bigHoleDiameter,
lineSegPara,
filterParam,
growParam,
groundCalibPara,
workpiecePositioning,
&errCode);
long t2 = (long)GetTickCount64();
if (errCode == SX_ERR_UNKNOWN_OBJECT)
printf("%s: %d(ms), 有异物残留! ...", _scan_file, (int)(t2 - t1));
else if (errCode == SX_ERR_ZERO_OBJECTS)
printf("%s: %d(ms), 无产品! ...", _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_RGBD(_scan_file, scanLines, workpiecePositioning);
sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositioning);
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, workpiecePositioning, rpy, angleDrawLen);
printf("done\n");
}
}
#endif
}
#define TPF5_TEST_GROUP 14
//拓普发工件孔定位(工件定位)
void TuoPuFa_holePosition_test5(void)
{
const char* dataPath[TPF5_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/1层/", //0
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/2层/", //1
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/3层/", //2
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/4层/", //3
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/5层/", //4
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/6层/", //5
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/7层/", //6
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/8层/", //7
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/9层/", //8
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/10层/", //9
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/11层/", //10
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/12层/", //11
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/13层/", //12
"F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件5/14层/", //13
};
SVzNLRange fileIdx[TPF5_TEST_GROUP] = {
{1,10}, {1, 10}, {1,10}, {1,10}, {1, 10},
{1,11}, {1, 10}, {1,11}, {1,10}, {1,10},
{1, 10}, {1,10}, {1,11}, {1,10}
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_CALIB_PARA
char _calib_datafile[256];
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/调平数据.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)
{
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, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/ground_calib_para.txt");
_outputCalibPara(calibFile, calibPara);
char _out_file[256];
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦项目/拓普发工件孔定位/工件2/scanData_ground_calib_verify.txt");
int headNullLines = 0;
_outputScanDataFile_vector(_out_file, scanData, false, &headNullLines);
printf("%s: calib done!\n", _calib_datafile);
}
#endif
#if TEST_COMPUTE_HOLE
for (int grp = 0; grp < TPF5_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 =4;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Jh26B074.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
_removeZeroLines(scanLines);
if (scanLines.size() == 0)
continue;
long t1 = (long)GetTickCount64();//统计时间
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 6.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 28;
SSG_lineSegParam lineSegPara;
lineSegPara.distScale = workpiecePara.H / 2; //此参数用于确定
lineSegPara.segGapTh_y = 15.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 5.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 1.5; //mm
growParam.minVTypeTreeLen = 1.5; //mm
int errCode = 0;
std::vector< WD_workpieceInfo> workpiecePositioning;
wd_workpieceHolePositioning_2(
scanLines,
workpiecePara,
lineSegPara,
filterParam,
growParam,
groundCalibPara,
workpiecePositioning,
&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_RGBD(_scan_file, scanLines, workpiecePositioning);
sprintf_s(calibFile, "%sresult/LaserLine%d_hole_info.txt", dataPath[grp], fidx);
_outputWorkpieceInfo(calibFile, workpiecePositioning);
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, workpiecePositioning, rpy, angleDrawLen);
printf("done\n");
}
}
#endif
}
//华航孔定位
#define HH_TEST_GROUP 6
void HuaHang_holePosition_test(void)
{
const char* dataPath[HH_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据1/", //0
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据2/1/", //1
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据2/2/", //2
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据2/3/", //3
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据4/好的/", //4
"F:/ShangGu/项目/冠钦项目/华航孔定位/圆孔识别_数据4/坏的/", //5
};
SVzNLRange fileIdx[HH_TEST_GROUP] = {
{1,15}, {1, 21},{1,19}, {1,13},
{1, 4}, {4,13},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_HOLE
for (int grp = 5; grp <= 5; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =17;
char _scan_file[256];
sprintf_s(_scan_file, "%sLaserData_%d.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_lineSegParam lineSegPara;
lineSegPara.distScale = 25.0;
lineSegPara.segGapTh_y = 25.0; //
lineSegPara.segGapTh_z = 0.0; //z方向间隔大于10mm认为是分段
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;
SSG_outlierFilterParam filterParam;
filterParam.continuityTh = 20.0; //噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声。若长度小于outlierLen 视为噪声
filterParam.outlierTh = 5;
SSG_treeGrowParam growParam;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;//
growParam.minLTypeTreeLen = 1.0; //mm
growParam.minVTypeTreeLen = 1.0; //mm
WD_workpieceHoleParam workpiecePara;
workpiecePara.workpieceType = 0;
workpiecePara.holeDiameter = 6.0; //
workpiecePara.holeDist_W = 32.0;
workpiecePara.holeDist_L = 40.0;
workpiecePara.xLen = 44;
workpiecePara.yLen = 70;
workpiecePara.H = 47;
int errCode = 0;
std::vector< WD_HolePositionInfo> holePositioning;
wd_HolePositioning(scanLines, lineSegPara, cornerParam, filterParam, growParam, holePositioning, &errCode);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
//输出测试结果
double dirLen = 20;
sprintf_s(_scan_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_HoleInfo(_scan_file, scanLines, holePositioning, dirLen);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo(_scan_file, holePositioning);
}
}
#endif
}
//微力砂轮孔定位
#define WELI_DISC_TEST_GROUP 2
void Weili_grindingDiscHolePosition_test(void)
{
const char* dataPath[WELI_DISC_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/砂轮400/", //0
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/砂轮610/", //1
};
SVzNLRange fileIdx[WELI_DISC_TEST_GROUP] = {
{1,3}, {1, 4}
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
for (int grp = 0; grp <= 1; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =17;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_ID019068.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;
int errCode = 0;
WD_HolePositionInfo discPose = sx_getDiscHolePose(
scanLines,
cornerParam,
&errCode);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
//输出测试结果
sprintf_s(_scan_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_HoleInfo_2(_scan_file, scanLines, discPose);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo_2(_scan_file, discPose);
}
}
}
//微力砂轮架子定位
#define WEILI_RACK_TEST_GROUP 5
void Weili_grindingDiscRackPosition_test(void)
{
const char* dataPath[WEILI_RACK_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/架子_右上角/", //0
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/架子_右下角/", //1
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/架子_中间/", //2
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/架子_左上角/", //3
"F:/ShangGu/项目/冠钦项目/郑州微力_砂轮和架子定位/数据/架子_左下角/", //4
};
SVzNLRange fileIdx[WEILI_RACK_TEST_GROUP] = {
{1, 16},{1,15}, {1,15}, {1, 15}, {1,15},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if TEST_COMPUTE_HOLE
for (int grp = 0; grp <= 4; grp++)
{
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
{
//fidx =17;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_ID019068.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;
int errCode = 0;
//砂轮盘架子中心定位
SSG_pointPose discRackPose = sx_getDiscRackCenterPosition(
scanLines,
cornerParam,
&errCode);
long t2 = (long)GetTickCount64();
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
//输出测试结果
sprintf_s(_scan_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
_outputRGBDResult_RGBD_2(_scan_file, scanLines, discRackPose);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo_3(_scan_file, discRackPose);
}
}
#endif
}
//山东本事机电轮胎定位
#define BENSHI_COMPUTE_CALIB_PARA 0
#define BENSHI_HOLE_POSITION 1
#define BENSHI_TIRE_TEST_GROUP 1
void Benshi_tirePosition_test(void)
{
const char* dataPath[BENSHI_TIRE_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/山东本事机电轮胎抓取/数据/", //0
};
SVzNLRange fileIdx[BENSHI_TIRE_TEST_GROUP] = {
{1,34},
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if BENSHI_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_Ik256400.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);
}
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 BENSHI_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 =18;
char _scan_file[256];
sprintf_s(_scan_file, "%s%d_LaserData_Ik256400.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_tireParam tireParam;
tireParam.diameter = 500;
tireParam.thickness = 140;
int errCode = 0;
std::vector<WD_HolePositionInfo> tirePositions;
sx_getTireHolePose(
scanLines,
cornerParam,
groundCalibPara,
tireParam,
tirePositions,
&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, tirePositions, dirLen);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo(_scan_file, tirePositions);
}
}
#endif
}
//海瑞马
#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 = 72;
rotorParam.rotorH = 40.0;
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
}
#define JIURUI_COMPUTE_CALIB_PARA 0
#define JIURUI_HOLE_POSITION 1
#define JIURUI_TIRE_TEST_GROUP 2
void JiuRui_workpiecePosition_test(void)
{
const char* dataPath[JIURUI_TIRE_TEST_GROUP] = {
"F:/ShangGu/项目/冠钦项目/北京玖瑞/工件识别/工件数据/1367mm/",//0
"F:/ShangGu/项目/冠钦项目/北京玖瑞/工件识别/工件数据/距离工件1183mm/", //1
};
SVzNLRange fileIdx[JIURUI_TIRE_TEST_GROUP] = {
{1,8},{1,6}
};
const char* ver = wd_workpieceHolePositioningVersion();
printf("ver:%s\n", ver);
#if JIURUI_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_Ik256400.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);
}
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 JIURUI_HOLE_POSITION
for (int grp = 0; grp <= 1; 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_Hi229229_sampleDown.txt", dataPath[grp], fidx);
std::vector<std::vector< SVzNL3DPosition>> scanLines;
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanLines);
if (scanLines.size() == 0)
continue;
#if 0
//抽样
std::vector<std::vector< SVzNL3DPosition>> sampleData;
int sampleLines = (int)scanLines.size() / 4;
sampleData.resize(sampleLines);
int sLine = 0;
for (int i = 0; i < (int)scanLines.size(); i++)
{
if (i % 4 == 0)
{
sampleData[sLine].resize(scanLines[i].size());
std::copy(scanLines[i].begin(), scanLines[i].end(), sampleData[sLine].begin()); // 使用std::copy算法
sLine++;
if (sLine >= sampleLines)
break;
}
}
//写入
sprintf_s(_scan_file, "%s%d_LaserData_Hi229229_sampleDown.txt", dataPath[grp], fidx);
int headNullLines = 0;
_outputScanDataFile_vector(_scan_file, sampleData, false, &headNullLines);
continue;
#endif
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_JiuruiWorkpieceParam workpieceParam;
workpieceParam.len = 320;
workpieceParam.width = 140;
workpieceParam.thickness = 48;
int errCode = 0;
std::vector<SSG_pointPose> workpiecePositions;
Jiurui_getWorkpiecePose(
scanLines,
cornerParam,
groundCalibPara,
workpieceParam,
workpiecePositions,
&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);
SSG_pointPose a_pose;
memset(&a_pose, 0, sizeof(SSG_pointPose));
if (workpiecePositions.size() > 0)
a_pose = workpiecePositions[0];
_outputRGBDResult_RGBD_2(_scan_file, scanLines, a_pose);
sprintf_s(_scan_file, "%sresult\\LaserLine%d_corner_info.txt", dataPath[grp], fidx);
_outputHoleInfo_3(_scan_file, a_pose);
}
}
#endif
}
typedef enum
{
keSG_拓普发孔定位_工件1 = 0,
keSG_拓普发孔定位_工件2,
keSG_拓普发孔定位_工件3,
keSG_拓普发孔定位_工件4,
keSG_拓普发孔定位_工件5,
keSG_拓普发孔定位_工件全测试,
keSG_华航孔定位,
keSG_微力砂轮盘定位,
keSG_微力砂轮架子定位,
keSG_山东本事轮胎定位,
keSG_宁波海瑞马转子芯定位,
keSG_北京玖瑞工件定位,
} ESG_testMode;
int main()
{
//ESG_testMode testMode = keSG_拓普发孔定位_工件1;
//ESG_testMode testMode = keSG_拓普发孔定位_工件2;
//ESG_testMode testMode = keSG_拓普发孔定位_工件3;
//ESG_testMode testMode = keSG_拓普发孔定位_工件4;
//ESG_testMode testMode = keSG_拓普发孔定位_工件5;
ESG_testMode testMode = keSG_拓普发孔定位_工件全测试;
//ESG_testMode testMode = keSG_华航孔定位;
//ESG_testMode testMode = keSG_微力砂轮盘定位;
//ESG_testMode testMode = keSG_微力砂轮架子定位;
//ESG_testMode testMode = keSG_山东本事轮胎定位;
//ESG_testMode testMode = keSG_宁波海瑞马转子芯定位;
//ESG_testMode testMode = keSG_北京玖瑞工件定位;
if (keSG_拓普发孔定位_工件1 == testMode)
TuoPuFa_holePosition_test();
else if (keSG_拓普发孔定位_工件2 == testMode)
TuoPuFa_holePosition_test2();
else if (keSG_拓普发孔定位_工件3 == testMode)
TuoPuFa_holePosition_test3();
else if (keSG_拓普发孔定位_工件4 == testMode)
TuoPuFa_holePosition_test4();
else if (keSG_拓普发孔定位_工件5 == testMode)
TuoPuFa_holePosition_test5();
else if (keSG_拓普发孔定位_工件全测试 == testMode)
{
TuoPuFa_holePosition_test();
TuoPuFa_holePosition_test2();
TuoPuFa_holePosition_test3();
TuoPuFa_holePosition_test4();
TuoPuFa_holePosition_test5();
}
else if (keSG_华航孔定位 == testMode)
HuaHang_holePosition_test();
else if (keSG_微力砂轮盘定位 == testMode)
Weili_grindingDiscHolePosition_test();
else if (keSG_微力砂轮架子定位 == testMode)
Weili_grindingDiscRackPosition_test();
else if (keSG_山东本事轮胎定位 == testMode)
Benshi_tirePosition_test();
else if (keSG_宁波海瑞马转子芯定位 == testMode)
HaiRuiMa_rotorCorePosition_test();
else if (keSG_北京玖瑞工件定位 == testMode)
JiuRui_workpiecePosition_test();
}