拆包更新算法
This commit is contained in:
parent
74f9545a65
commit
99881767bb
@ -224,6 +224,7 @@ int DetectPresenter::DetectBag(
|
|||||||
// 1. 使用成员变量算法参数(已在初始化时从XML读取)
|
// 1. 使用成员变量算法参数(已在初始化时从XML读取)
|
||||||
LOG_INFO("[Algo Thread] Using algorithm parameters from XML configuration\n");
|
LOG_INFO("[Algo Thread] Using algorithm parameters from XML configuration\n");
|
||||||
LOG_INFO(" Bag: L=%.1f, W=%.1f, H=%.1f\n",algoParam.bagParam.bagL, algoParam.bagParam.bagW, algoParam.bagParam.bagH);
|
LOG_INFO(" Bag: L=%.1f, W=%.1f, H=%.1f\n",algoParam.bagParam.bagL, algoParam.bagParam.bagW, algoParam.bagParam.bagH);
|
||||||
|
LOG_INFO(" supportRotate=%d, outputMode=%d\n",algoParam.supportRotate, algoParam.outputMode);
|
||||||
LOG_INFO(" Filter: continuityTh=%.1f, outlierTh=%.1f\n", algoParam.filterParam.continuityTh, algoParam.filterParam.outlierTh);
|
LOG_INFO(" Filter: continuityTh=%.1f, outlierTh=%.1f\n", algoParam.filterParam.continuityTh, algoParam.filterParam.outlierTh);
|
||||||
|
|
||||||
LOG_INFO(" Corner: minEndingGap=%.1f, minEndingGap_z=%.1f, scale=%.1f, cornerTh=%.1f, jumpCornerTh_1=%.1f, jumpCornerTh_2=%.1f\n",
|
LOG_INFO(" Corner: minEndingGap=%.1f, minEndingGap_z=%.1f, scale=%.1f, cornerTh=%.1f, jumpCornerTh_1=%.1f, jumpCornerTh_2=%.1f\n",
|
||||||
|
|||||||
@ -894,6 +894,8 @@ int GrabBagPresenter::InitAlgorithmParams()
|
|||||||
LOG_INFO("projectType: %s\n", ProjectTypeToString(m_projectType).c_str());
|
LOG_INFO("projectType: %s\n", ProjectTypeToString(m_projectType).c_str());
|
||||||
LOG_INFO("Algorithm parameters initialized successfully via ParameterManager\n");
|
LOG_INFO("Algorithm parameters initialized successfully via ParameterManager\n");
|
||||||
|
|
||||||
|
_UpdateCurrentExecutionParams();
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
#define GRABBAG_VERSION_STRING "1.3.6"
|
#define GRABBAG_VERSION_STRING "1.3.6"
|
||||||
#define GRABBAG_BUILD_STRING "1"
|
#define GRABBAG_BUILD_STRING "2"
|
||||||
#define GRABBAG_FULL_VERSION_STRING "V" GRABBAG_VERSION_STRING "_" GRABBAG_BUILD_STRING
|
#define GRABBAG_FULL_VERSION_STRING "V" GRABBAG_VERSION_STRING "_" GRABBAG_BUILD_STRING
|
||||||
|
|
||||||
// 获取版本信息的便捷函数
|
// 获取版本信息的便捷函数
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
# 1.3.6
|
# 1.3.6
|
||||||
|
## build_2 20260205
|
||||||
|
1. 更新算法
|
||||||
|
|
||||||
## build_1 20260129
|
## build_1 20260129
|
||||||
1. 增加授权判断
|
1. 增加授权判断
|
||||||
|
|
||||||
|
|||||||
@ -301,7 +301,7 @@ struct VrAlgorithmParams
|
|||||||
VrHsvCmpParam hsvCmpParam;
|
VrHsvCmpParam hsvCmpParam;
|
||||||
VrRgbColorPattern rgbColorPattern;
|
VrRgbColorPattern rgbColorPattern;
|
||||||
VrColorTemplateParam colorTemplateParam;
|
VrColorTemplateParam colorTemplateParam;
|
||||||
int supportRotate = 1;
|
int supportRotate = 0;
|
||||||
int outputMode = 0; // 输出模式:0 - 从大到小, 1 - 从小到大
|
int outputMode = 0; // 输出模式:0 - 从大到小, 1 - 从小到大
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -19,32 +19,32 @@
|
|||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_x" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2002" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_x" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2002" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_y" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2004" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_y" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2004" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_z" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2006" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_z" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2006" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_r" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2008" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_r" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2008" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_p" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2010" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_p" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2010" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
</DATA>
|
</DATA>
|
||||||
<DATA Name="1_y" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2012" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="0" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
<DATA Name="1_y" BLOCK="2" PrtcTYPE="2" Unit="--" ShowType="0" Addr="2012" Gain="1" Size="2" BitOffset="0" BitNum="32" Range="--" Color="" ByteOder="0" WordOder="1" IntervalTime="0" IsShow="1" IsBRead="1" IsBWrite="0">
|
||||||
<TIMEOUT Time="2000" ResendCount="0" />
|
<TIMEOUT Time="2000" ResendCount="0" />
|
||||||
<CURVE IsShow="0" />
|
<CURVE IsShow="0" />
|
||||||
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
<VALUE Stategy="0" TimeBngrWay="0" Coef_a="0" Coef_b="0" Coef_c="0" Coef_d="0" Coef_e="0" ResetStep="0" XInvl="1000" MaxRadom="0" MinRadom="0" MaxValue="0" MinValue="0" />
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -25,6 +25,20 @@ typedef struct
|
|||||||
double yawAngle; //偏转角:绕Z轴的偏转, 弧度
|
double yawAngle; //偏转角:绕Z轴的偏转, 弧度
|
||||||
}SSG_6AxisAttitude;
|
}SSG_6AxisAttitude;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
}SWD3DPoint;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int lineIdx;
|
||||||
|
int ptIdx;
|
||||||
|
SWD3DPoint point;
|
||||||
|
}SWDIndexing3DPoint;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
bool validFlag; //指示结果是否有效
|
bool validFlag; //指示结果是否有效
|
||||||
@ -48,6 +62,17 @@ typedef struct
|
|||||||
int idx;
|
int idx;
|
||||||
}SSG_intPair;
|
}SSG_intPair;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int featurType;
|
||||||
|
int featureIdx_v;
|
||||||
|
int featureIdx_h;
|
||||||
|
int clusterID;
|
||||||
|
int flag;
|
||||||
|
int lineIdx;
|
||||||
|
int ptIdx;
|
||||||
|
}SSG_featureClusteringInfo;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
double left;
|
double left;
|
||||||
@ -56,6 +81,12 @@ typedef struct
|
|||||||
double bottom;
|
double bottom;
|
||||||
}SSG_ROIRectD;
|
}SSG_ROIRectD;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SVzNL3DPoint center;
|
||||||
|
double radius;
|
||||||
|
}SWD_HoleInfo;
|
||||||
|
|
||||||
struct HSV {
|
struct HSV {
|
||||||
double h; // 色相 (0-360)
|
double h; // 色相 (0-360)
|
||||||
double s; // 饱和度 (0-1)
|
double s; // 饱和度 (0-1)
|
||||||
@ -157,6 +188,20 @@ typedef struct
|
|||||||
double jumpCornerTh_2;
|
double jumpCornerTh_2;
|
||||||
}SSG_cornerParam;
|
}SSG_cornerParam;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double segGapTh_y; //y方向连续段门限。大于此门限,为不连续
|
||||||
|
double segGapTh_z; //z方向连续段门限。大于此门限,为不连续
|
||||||
|
double distScale; //计算方向角的窗口比例尺
|
||||||
|
}SSG_lineSegParam;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double minJumpZ; //z方向跳变门限
|
||||||
|
double minK; //跳变的最小斜率
|
||||||
|
SVzNLRangeD widthRange; //z方向连续段门限。大于此门限,为不连续
|
||||||
|
}SSG_raisedFeatureParam;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
double scale_angle; //计算方向角的窗口比例尺
|
double scale_angle; //计算方向角的窗口比例尺
|
||||||
@ -184,6 +229,7 @@ typedef struct
|
|||||||
int endPtIdx;
|
int endPtIdx;
|
||||||
SVzNL3DPoint startPt;
|
SVzNL3DPoint startPt;
|
||||||
SVzNL3DPoint endPt;
|
SVzNL3DPoint endPt;
|
||||||
|
double featureValue;
|
||||||
}SWD_segFeature;
|
}SWD_segFeature;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -247,6 +293,18 @@ typedef struct
|
|||||||
int angleChkScalePos; //仅用于加速angleCheck的速度
|
int angleChkScalePos; //仅用于加速angleCheck的速度
|
||||||
}SSG_featureTree;
|
}SSG_featureTree;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int treeState;
|
||||||
|
int treeType;
|
||||||
|
int sLineIdx;
|
||||||
|
int eLineIdx;
|
||||||
|
double tree_value;
|
||||||
|
SSG_ROIRectD roi;
|
||||||
|
std::vector< SSG_basicFeatureGap> treeNodes;
|
||||||
|
int angleChkScalePos; //仅用于加速angleCheck的速度
|
||||||
|
}SSG_gapFeatureTree;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int treeState;
|
int treeState;
|
||||||
@ -483,4 +541,35 @@ typedef struct
|
|||||||
{
|
{
|
||||||
SVzNL3DPoint pt1;
|
SVzNL3DPoint pt1;
|
||||||
SVzNL3DPoint pt2;
|
SVzNL3DPoint pt2;
|
||||||
}SWD_3DPointPair;
|
}SWD_3DPointPair;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int pkId;
|
||||||
|
int lineIdx;
|
||||||
|
int ptIdx;
|
||||||
|
int cptIndex; //圆周扫描上的点序
|
||||||
|
//double cornerAngle; //以点为中心的两侧弦的夹角
|
||||||
|
double R;
|
||||||
|
double angle;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
}SWD_polarPt;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int cptIndex;
|
||||||
|
int L1_ptIndex;
|
||||||
|
int L2_ptIndex;
|
||||||
|
double cornerAngle;
|
||||||
|
int cornerDir;
|
||||||
|
}SWD_polarPeakInfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int clusterIdx;
|
||||||
|
int ptSize;
|
||||||
|
SVzNL3DRangeD roi3D;
|
||||||
|
SVzNLRect roi2D;
|
||||||
|
}SWD_clustersInfo;
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#define SG_ERR_LABEL_INFO_ERROR -1004
|
#define SG_ERR_LABEL_INFO_ERROR -1004
|
||||||
#define SG_ERR_INVLD_SORTING_MODE -1005
|
#define SG_ERR_INVLD_SORTING_MODE -1005
|
||||||
#define SG_ERR_INVLD_Q_SCALE -1006
|
#define SG_ERR_INVLD_Q_SCALE -1006
|
||||||
|
#define SG_ERR_ZERO_OBJECTS -1007
|
||||||
|
|
||||||
//BQ_workpiece
|
//BQ_workpiece
|
||||||
#define SX_ERR_INVLD_VTREE_NUM -2001
|
#define SX_ERR_INVLD_VTREE_NUM -2001
|
||||||
@ -16,6 +17,7 @@
|
|||||||
#define SX_ERR_ZERO_CONTOUR_PT -2005
|
#define SX_ERR_ZERO_CONTOUR_PT -2005
|
||||||
#define SX_ERR_INVLID_RPEAK_NUM -2006
|
#define SX_ERR_INVLID_RPEAK_NUM -2006
|
||||||
#define SX_ERR_INVLID_RPEAK_PAIR -2007
|
#define SX_ERR_INVLID_RPEAK_PAIR -2007
|
||||||
|
#define SX_ERR_INVLID_MARK_NUM -2008
|
||||||
|
|
||||||
//땍綾婁혤
|
//땍綾婁혤
|
||||||
#define SX_ERR_INVLID_CUTTING_Z -2101
|
#define SX_ERR_INVLID_CUTTING_Z -2101
|
||||||
@ -23,3 +25,7 @@
|
|||||||
|
|
||||||
//뀔관
|
//뀔관
|
||||||
#define SX_BAG_TRAY_EMPTY -2201
|
#define SX_BAG_TRAY_EMPTY -2201
|
||||||
|
|
||||||
|
//汽车轮眉高度测量
|
||||||
|
#define SX_ERR_INVALID_ARC -2301
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -9,6 +9,14 @@
|
|||||||
#include "VrLog.h"
|
#include "VrLog.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
|
// 辅助函数:去除字符串末尾的 \r 字符(处理 Windows 格式的 CR LF 换行符)
|
||||||
|
static inline void TrimCarriageReturn(std::string& str)
|
||||||
|
{
|
||||||
|
if (!str.empty() && str.back() == '\r') {
|
||||||
|
str.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LaserDataLoader::LaserDataLoader()
|
LaserDataLoader::LaserDataLoader()
|
||||||
{
|
{
|
||||||
m_lastError.clear();
|
m_lastError.clear();
|
||||||
@ -57,12 +65,15 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName,
|
|||||||
|
|
||||||
bool bFindLineNum = true;
|
bool bFindLineNum = true;
|
||||||
int nLaserPointIdx = 0;
|
int nLaserPointIdx = 0;
|
||||||
|
|
||||||
while (std::getline(inputFile, line)) {
|
while (std::getline(inputFile, line)) {
|
||||||
|
// 去除行末的 \r 字符(处理 Windows 格式的 CR LF 换行符)
|
||||||
|
TrimCarriageReturn(line);
|
||||||
|
|
||||||
if (line.find("LineNum:") == 0) {
|
if (line.find("LineNum:") == 0) {
|
||||||
sscanf(line.c_str(), "LineNum:%d", &lineNum);
|
sscanf(line.c_str(), "LineNum:%d", &lineNum);
|
||||||
} else if (line.find("DataType:") == 0) {
|
} else if (line.find("DataType:") == 0) {
|
||||||
|
|
||||||
} else if (line.find("Line_") == 0) {
|
} else if (line.find("Line_") == 0) {
|
||||||
|
|
||||||
if(false == bFindLineNum) {
|
if(false == bFindLineNum) {
|
||||||
@ -513,6 +524,9 @@ int LaserDataLoader::_GetLaserType(const std::string& fileName, EVzResultDataTyp
|
|||||||
|
|
||||||
bool bFind = false;
|
bool bFind = false;
|
||||||
while (std::getline(inputFile, linedata)) {
|
while (std::getline(inputFile, linedata)) {
|
||||||
|
// 去除行末的 \r 字符(处理 Windows 格式的 CR LF 换行符)
|
||||||
|
TrimCarriageReturn(linedata);
|
||||||
|
|
||||||
if (linedata.find("{") == 0) {
|
if (linedata.find("{") == 0) {
|
||||||
// 修复正则表达式以匹配实际数据格式
|
// 修复正则表达式以匹配实际数据格式
|
||||||
// XYZ格式: {x,y,z}-{leftX,leftY}-{rightX,rightY}
|
// XYZ格式: {x,y,z}-{leftX,leftY}-{rightX,rightY}
|
||||||
|
|||||||
@ -6,9 +6,6 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// 静态成员初始化
|
|
||||||
CGlLineLaserDevice* CGlLineLaserDevice::s_pInstance = nullptr;
|
|
||||||
|
|
||||||
CGlLineLaserDevice::CGlLineLaserDevice()
|
CGlLineLaserDevice::CGlLineLaserDevice()
|
||||||
: m_nDeviceId(0)
|
: m_nDeviceId(0)
|
||||||
, m_bDeviceOpen(false)
|
, m_bDeviceOpen(false)
|
||||||
@ -65,7 +62,7 @@ int CGlLineLaserDevice::OpenDevice(const char* sIP, bool bRGBD, bool bSwing, boo
|
|||||||
memset(ðConfig, 0, sizeof(ethConfig));
|
memset(ðConfig, 0, sizeof(ethConfig));
|
||||||
|
|
||||||
if (sIP && strlen(sIP) > 0) {
|
if (sIP && strlen(sIP) > 0) {
|
||||||
LOG_ERROR("open IP address format: %s\n", sIP);
|
LOG_DEBUG("open IP address format: %s\n", sIP);
|
||||||
// 解析IP字符串 "x.x.x.x"
|
// 解析IP字符串 "x.x.x.x"
|
||||||
int ip[4];
|
int ip[4];
|
||||||
if (sscanf(sIP, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
|
if (sscanf(sIP, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
|
||||||
@ -197,24 +194,10 @@ int CGlLineLaserDevice::StartDetect(VzNL_AutoOutputLaserLineExCB fCallFunc, EVzR
|
|||||||
m_bStopDetect = false;
|
m_bStopDetect = false;
|
||||||
m_ullFrameIndex = 0;
|
m_ullFrameIndex = 0;
|
||||||
|
|
||||||
// 设置回调实例指针
|
// 启动数据采集线程(主动轮询模式)
|
||||||
s_pInstance = this;
|
|
||||||
|
|
||||||
// 设置批处理回调
|
|
||||||
int ret = GLX8_2_SetBatchOneTimeDataHandler(m_nDeviceId, BatchDataCallback);
|
|
||||||
if (ret != 0) {
|
|
||||||
LOG_ERROR("GLX8_2_SetBatchOneTimeDataHandler failed: %d\n", ret);
|
|
||||||
return ERR_CODE(DEV_CTRL_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始批处理采集(立即开始)
|
|
||||||
ret = GLX8_2_StartMeasureWithCallback(m_nDeviceId, 0);
|
|
||||||
if (ret != 0) {
|
|
||||||
LOG_ERROR("GLX8_2_StartMeasureWithCallback failed: %d\n", ret);
|
|
||||||
return ERR_CODE(DEV_CTRL_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bDetecting = true;
|
m_bDetecting = true;
|
||||||
|
m_detectThread = std::thread(&CGlLineLaserDevice::DetectThreadFunc, this);
|
||||||
|
|
||||||
LOG_DEBUG("Detection started\n");
|
LOG_DEBUG("Detection started\n");
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@ -239,8 +222,12 @@ int CGlLineLaserDevice::StopDetect()
|
|||||||
LOG_ERROR("GLX8_2_StopMeasure failed: %d\n", ret);
|
LOG_ERROR("GLX8_2_StopMeasure failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 等待线程结束
|
||||||
|
if (m_detectThread.joinable()) {
|
||||||
|
m_detectThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
m_bDetecting = false;
|
m_bDetecting = false;
|
||||||
s_pInstance = nullptr;
|
|
||||||
|
|
||||||
// 通知状态变化
|
// 通知状态变化
|
||||||
if (m_pStatusCallback) {
|
if (m_pStatusCallback) {
|
||||||
@ -253,48 +240,89 @@ int CGlLineLaserDevice::StopDetect()
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批处理数据回调(静态函数)
|
// 数据采集线程函数(主动轮询模式,参考 test_deal_atch_datas)
|
||||||
void CGlLineLaserDevice::BatchDataCallback(const GLX8_2_STR_CALLBACK_INFO* info, const GLX8_2_Data DataObj)
|
void CGlLineLaserDevice::DetectThreadFunc()
|
||||||
{
|
{
|
||||||
if (s_pInstance) {
|
LOG_DEBUG("Detect thread started\n");
|
||||||
s_pInstance->ProcessBatchData(info, DataObj);
|
|
||||||
|
while (!m_bStopDetect) {
|
||||||
|
// 启动批处理(参考 test_deal_atch_datas)
|
||||||
|
int ret = GLX8_2_StartMeasure(m_nDeviceId, 5000); // 5秒超时
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERROR("GLX8_2_StartMeasure failed: %d\n", ret);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待一小段时间让设备准备好
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
|
||||||
|
// 获取批处理数据(参考 test_batch_datas)
|
||||||
|
GetBatchData();
|
||||||
|
|
||||||
|
// 批处理完成后等待一段时间再开始下一次
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("Detect thread stopped\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理批处理数据
|
// 获取批处理数据(参考 test_batch_datas 的流程)
|
||||||
void CGlLineLaserDevice::ProcessBatchData(const GLX8_2_STR_CALLBACK_INFO* info, const GLX8_2_Data DataObj)
|
void CGlLineLaserDevice::GetBatchData()
|
||||||
{
|
{
|
||||||
if (!m_pDetectCallback || m_bStopDetect) {
|
GLX8_2_STR_CALLBACK_INFO info;
|
||||||
return;
|
memset(&info, 0, sizeof(info));
|
||||||
}
|
|
||||||
|
|
||||||
int width = info->xPoints;
|
const int maxBatchLines = m_nBatchLines;
|
||||||
int batchCount = info->BatchPoints;
|
|
||||||
LOG_DEBUG("BatchPoints: %d, xPoints: %d\n", batchCount, width);
|
|
||||||
|
|
||||||
// 获取整个批次的轮廓数据(连续内存,大小为 BatchPoints * xPoints)
|
// 确保缓存足够大
|
||||||
int32_t* batchProfileData = GLX8_2_GetBatchProfilePoint(DataObj, 0);
|
size_t totalPoints = static_cast<size_t>(m_nProfileWidth) * maxBatchLines;
|
||||||
if (!batchProfileData) {
|
|
||||||
LOG_WARNING("No profile data in batch\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拷贝整个批次数据到本地缓存,避免回调期间数据被覆盖
|
|
||||||
size_t totalPoints = static_cast<size_t>(batchCount) * width;
|
|
||||||
if (m_profileBuffer.size() < totalPoints) {
|
if (m_profileBuffer.size() < totalPoints) {
|
||||||
m_profileBuffer.resize(totalPoints);
|
m_profileBuffer.resize(totalPoints);
|
||||||
}
|
}
|
||||||
memcpy(m_profileBuffer.data(), batchProfileData, totalPoints * sizeof(int32_t));
|
if (m_intensityBuffer.size() < totalPoints) {
|
||||||
|
m_intensityBuffer.resize(totalPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> encoderBuffer(maxBatchLines);
|
||||||
|
|
||||||
|
// 使用 GLX8_2_ReceiveDataAuto 顺序获取批处理数据
|
||||||
|
int ret = GLX8_2_ReceiveDataAuto(m_nDeviceId, &info,
|
||||||
|
m_profileBuffer.data(),
|
||||||
|
m_intensityBuffer.data(),
|
||||||
|
encoderBuffer.data());
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_WARNING("GLX8_2_ReceiveDataAuto failed: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int batchCount = info.BatchPoints;
|
||||||
|
int width = info.xPoints;
|
||||||
|
|
||||||
|
if (batchCount <= 0 || width <= 0) {
|
||||||
|
LOG_WARNING("Invalid batch data: batchCount=%d, width=%d\n", batchCount, width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("Received batch: %d lines, width: %d, startEncoder: %d\n",
|
||||||
|
batchCount, width, info.startEncoder);
|
||||||
|
|
||||||
// 确保位置缓存足够大
|
// 确保位置缓存足够大
|
||||||
if (m_positionBuffer.size() < static_cast<size_t>(width)) {
|
if (m_positionBuffer.size() < static_cast<size_t>(width)) {
|
||||||
m_positionBuffer.resize(width);
|
m_positionBuffer.resize(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 逐行处理数据并回调
|
// 逐行处理数据并回调(转换为xyz点云数据)
|
||||||
for (int lineIdx = 0; lineIdx < batchCount; lineIdx++) {
|
for (int lineIdx = 0; lineIdx < batchCount; lineIdx++) {
|
||||||
|
if (m_bStopDetect) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// 计算当前行在缓存中的偏移
|
// 计算当前行在缓存中的偏移
|
||||||
const int32_t* lineProfile = m_profileBuffer.data() + static_cast<size_t>(lineIdx) * width;
|
const int32_t* lineProfile = m_profileBuffer.data() + static_cast<size_t>(lineIdx) * width;
|
||||||
|
|
||||||
|
// 转换为xyz坐标
|
||||||
ConvertProfileToPosition(lineProfile, width, lineIdx);
|
ConvertProfileToPosition(lineProfile, width, lineIdx);
|
||||||
|
|
||||||
// 填充 SVzLaserLineData 结构
|
// 填充 SVzLaserLineData 结构
|
||||||
@ -309,32 +337,33 @@ void CGlLineLaserDevice::ProcessBatchData(const GLX8_2_STR_CALLBACK_INFO* info,
|
|||||||
laserLineData.llFrameIdx = m_ullFrameIndex;
|
laserLineData.llFrameIdx = m_ullFrameIndex;
|
||||||
laserLineData.llTimeStamp = std::chrono::duration_cast<std::chrono::microseconds>(
|
laserLineData.llTimeStamp = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
std::chrono::steady_clock::now().time_since_epoch()).count();
|
std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
laserLineData.nEncodeNo = info->startEncoder + lineIdx;
|
laserLineData.nEncodeNo = encoderBuffer[lineIdx]; // 使用实际的编码器值
|
||||||
laserLineData.fSwingAngle = 0.0f; // 线激光没有摆动角度
|
laserLineData.fSwingAngle = 0.0f; // 线激光没有摆动角度
|
||||||
laserLineData.bEndOnceScan = (lineIdx == batchCount - 1) ? VzTrue : VzFalse;
|
laserLineData.bEndOnceScan = (lineIdx == batchCount - 1) ? VzTrue : VzFalse;
|
||||||
|
|
||||||
// 回调
|
// 回调给上层应用
|
||||||
m_pDetectCallback(m_eDataType, &laserLineData, m_pDetectCallbackParam);
|
if (m_pDetectCallback) {
|
||||||
|
m_pDetectCallback(m_eDataType, &laserLineData, m_pDetectCallbackParam);
|
||||||
|
}
|
||||||
|
|
||||||
m_ullFrameIndex++;
|
m_ullFrameIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Processed %d lines, xPoints: %d\n", batchCount, width);
|
LOG_DEBUG("Processed %d lines, total frames: %llu\n", batchCount, m_ullFrameIndex);
|
||||||
// 如果是最后一个批处理,通知完成
|
|
||||||
if (info->returnStatus != 0) {
|
|
||||||
StopDetect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将轮廓数据转换为位置数据
|
// 将轮廓数据转换为位置数据
|
||||||
void CGlLineLaserDevice::ConvertProfileToPosition(const int32_t* profileData, int count, int lineIndex)
|
void CGlLineLaserDevice::ConvertProfileToPosition(const int32_t* profileData, int count, int lineIndex)
|
||||||
{
|
{
|
||||||
|
// lineIndex 参数保留用于未来扩展,当前使用 m_ullFrameIndex 计算全局偏移
|
||||||
|
(void)lineIndex;
|
||||||
|
|
||||||
// 确保缓存足够大
|
// 确保缓存足够大
|
||||||
if (m_positionBuffer.size() < static_cast<size_t>(count)) {
|
if (m_positionBuffer.size() < static_cast<size_t>(count)) {
|
||||||
m_positionBuffer.resize(count);
|
m_positionBuffer.resize(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算Y偏移(基于行索引)
|
// 计算Y偏移(基于全局帧索引)
|
||||||
double yOffset = static_cast<double>(m_ullFrameIndex) * m_dYPitch;
|
double yOffset = static_cast<double>(m_ullFrameIndex) * m_dYPitch;
|
||||||
|
|
||||||
// 转换每个点
|
// 转换每个点
|
||||||
|
|||||||
@ -127,10 +127,15 @@ private:
|
|||||||
// 内部方法
|
// 内部方法
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 数据采集线程函数
|
* @brief 数据采集线程函数(主动轮询模式,参考 test_deal_atch_datas)
|
||||||
*/
|
*/
|
||||||
void DetectThreadFunc();
|
void DetectThreadFunc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取批处理数据(参考 test_batch_datas 的流程)
|
||||||
|
*/
|
||||||
|
void GetBatchData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 将 gl_linelaser_sdk 的轮廓数据转换为 SVzNL3DPosition
|
* @brief 将 gl_linelaser_sdk 的轮廓数据转换为 SVzNL3DPosition
|
||||||
* @param profileData 轮廓数据(int32_t,单位0.01um)
|
* @param profileData 轮廓数据(int32_t,单位0.01um)
|
||||||
@ -139,19 +144,6 @@ private:
|
|||||||
* @return 转换后的位置数据数组
|
* @return 转换后的位置数据数组
|
||||||
*/
|
*/
|
||||||
void ConvertProfileToPosition(const int32_t* profileData, int count, int lineIndex);
|
void ConvertProfileToPosition(const int32_t* profileData, int count, int lineIndex);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 批处理数据回调(静态函数)
|
|
||||||
*/
|
|
||||||
static void BatchDataCallback(const GLX8_2_STR_CALLBACK_INFO* info, const GLX8_2_Data DataObj);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 处理批处理数据
|
|
||||||
*/
|
|
||||||
void ProcessBatchData(const GLX8_2_STR_CALLBACK_INFO* info, const GLX8_2_Data DataObj);
|
|
||||||
|
|
||||||
// 用于回调的实例指针
|
|
||||||
static CGlLineLaserDevice* s_pInstance;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CGLLINELASERDEVICE_H
|
#endif // CGLLINELASERDEVICE_H
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user