390 lines
12 KiB
C
Raw Normal View History

#ifndef IVRCONFIG_H
#define IVRCONFIG_H
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <cstring>
// 包含公共配置结构体
#include "VrCommonConfig.h"
#include "VrHandEyeCalibConfig.h"
/**
* @brief
*/
struct VrOutlierFilterParam
{
double continuityTh = 20.0; // 连续性阈值噪声滤除。当相邻点的z跳变大于此门限时检查是否为噪声
double outlierTh = 5.0; // 离群点判断阈值,若长度小于此值,视为噪声
};
/**
* @brief 线
*/
struct VrLineSegParam
{
double distScale = 3.0; // 计算方向角的窗口比例因子
double segGapTh_y = 15.0; // Y方向间隔阈值大于此值认为是分段
double segGapTh_z = 0.0; // Z方向间隔阈值大于此值认为是分段
};
/**
* @brief
*/
struct VrTreeGrowParam
{
int maxLineSkipNum = 2; // 生长时允许跳过的最大线条数
double yDeviation_max = 4.0; // 生长时允许的最大Y偏差
double maxSkipDistance = 0.0; // 最大跳跃距离
double zDeviation_max = 10.0; // 生长时允许的最大Z偏差
double minLTypeTreeLen = 2.0; // L型树的最小长度
double minVTypeTreeLen = 2.0; // V型树的最小长度
};
/**
* @brief
*/
struct VrWorkpieceHoleParam
{
int workpieceType = 0; // 工件类型
double holeDiameter = 6.0; // 孔直径 (mm)
2026-07-14 17:14:55 +08:00
double bigHoleDiameter = 33.0; // 大孔直径 (mm)工件3算法使用
double holeDist_L = 40.0; // 孔间距_长 (mm)
double holeDist_W = 32.0; // 孔间距_宽 (mm)
double xLen = 44.0; // x轴方向长度用于绘制平面 (mm)
double yLen = 70.0; // y轴方向长度用于绘制平面 (mm)
double H = 47.0; // 高度 (mm)
};
/**
* @brief PLC Modbus
*
* PLC D Modbus
* D寄存器 + 40001 = Modbus地址
* = D寄存器 + 1
*
*
* D1000 -> Modbus 41001 -> 1001
* D1002 -> Modbus 41003 -> 1003
* D2000 -> Modbus 42001 -> 2001
*/
struct VrPlcRegisterConfig
{
int addrPhotoRequest = 1001; // D1000: 拍照请求寄存器地址(读:=1触发拍照
int addrDataComplete = 1003; // D1002: 数据输出完成标志寄存器地址(写:=1完成
int addrCoordDataStart = 2002; // D2000: 坐标数据起始寄存器地址
// 显式赋值构造函数
VrPlcRegisterConfig& operator=(const VrPlcRegisterConfig& other) {
if (this != &other) {
addrPhotoRequest = other.addrPhotoRequest;
addrDataComplete = other.addrDataComplete;
addrCoordDataStart = other.addrCoordDataStart;
}
return *this;
}
// 显式复制构造函数
VrPlcRegisterConfig(const VrPlcRegisterConfig& other)
: addrPhotoRequest(other.addrPhotoRequest)
, addrDataComplete(other.addrDataComplete)
, addrCoordDataStart(other.addrCoordDataStart) {
}
// 默认构造函数
VrPlcRegisterConfig() = default;
};
/**
* @brief 姿
*
* 姿
*/
enum VrPoseOutputOrder
{
POSE_ORDER_RPY = 0, // Roll, Pitch, Yaw默认
POSE_ORDER_RYP = 1, // Roll, Yaw, Pitch
POSE_ORDER_PRY = 2, // Pitch, Roll, Yaw
POSE_ORDER_PYR = 3, // Pitch, Yaw, Roll
POSE_ORDER_YRP = 4, // Yaw, Roll, Pitch
POSE_ORDER_YPR = 5 // Yaw, Pitch, Roll
};
/**
* @brief
*
*
*
*/
enum VrDirVectorInvert
{
DIR_INVERT_NONE = 0, // 不反向
DIR_INVERT_XY = 1, // X和Y方向反向
DIR_INVERT_XZ = 2, // X和Z方向反向
DIR_INVERT_YZ = 3 // Y和Z方向反向默认兼容原有行为
};
/**
* @brief
*
* PLC
* PLC 使
*/
enum VrByteOrder
{
BYTE_ORDER_BIG_ENDIAN = 0, // 大端序 (ABCD) - 高字节在前
BYTE_ORDER_LITTLE_ENDIAN = 1 // 小端序 (DCBA) - 低字节在前
};
/**
* @brief PLC和机械臂服务端配置
*
* Doc/porotol.jpg
* - PLC-easy320: 192.168.0.88:502
* - : 192.168.0.90:502
*/
struct VrPlcRobotServerConfig
{
std::string plcServerIp = "192.168.0.88"; // PLC服务端IP地址汇川PLC-easy320
int plcServerPort = 502; // PLC服务端端口Modbus TCP默认502
std::string robotServerIp = "192.168.0.90"; // 机械臂服务端IP地址配天机械臂
int robotServerPort = 502; // 机械臂服务端端口Modbus TCP默认502
VrPlcRegisterConfig registerConfig; // PLC 寄存器地址配置
int poseOutputOrder = POSE_ORDER_RPY; // 姿态输出顺序默认RPY
int dirVectorInvert = DIR_INVERT_YZ; // 方向向量反向配置默认YZ反向兼容原有行为
int byteOrder = BYTE_ORDER_BIG_ENDIAN; // 数据字节序,默认大端序
// 显式赋值构造函数
VrPlcRobotServerConfig& operator=(const VrPlcRobotServerConfig& other) {
if (this != &other) {
plcServerIp = other.plcServerIp;
plcServerPort = other.plcServerPort;
robotServerIp = other.robotServerIp;
robotServerPort = other.robotServerPort;
registerConfig = other.registerConfig;
poseOutputOrder = other.poseOutputOrder;
dirVectorInvert = other.dirVectorInvert;
byteOrder = other.byteOrder;
}
return *this;
}
// 显式复制构造函数
VrPlcRobotServerConfig(const VrPlcRobotServerConfig& other)
: plcServerIp(other.plcServerIp)
, plcServerPort(other.plcServerPort)
, robotServerIp(other.robotServerIp)
, robotServerPort(other.robotServerPort)
, registerConfig(other.registerConfig)
, poseOutputOrder(other.poseOutputOrder)
, dirVectorInvert(other.dirVectorInvert)
, byteOrder(other.byteOrder) {
}
// 默认构造函数
VrPlcRobotServerConfig() = default;
};
2026-07-14 17:14:55 +08:00
/**
* @brief
*/
struct VrWorkpieceAlgorithmProfile
{
int workpieceNumber = 1;
VrWorkpieceHoleParam workpieceHoleParam;
VrLineSegParam lineSegParam;
VrOutlierFilterParam filterParam;
VrTreeGrowParam growParam;
VrWorkpieceAlgorithmProfile() = default;
explicit VrWorkpieceAlgorithmProfile(int number)
: workpieceNumber(number)
{
ApplyTestDefaults(number);
}
void ApplyTestDefaults(int number)
{
workpieceNumber = number;
workpieceHoleParam.workpieceType = 0;
workpieceHoleParam.holeDiameter = 6.0;
workpieceHoleParam.bigHoleDiameter = 33.0;
workpieceHoleParam.holeDist_L = 40.0;
workpieceHoleParam.holeDist_W = 32.0;
workpieceHoleParam.xLen = 44.0;
workpieceHoleParam.yLen = 70.0;
workpieceHoleParam.H = 47.0;
lineSegParam.distScale = 3.0;
lineSegParam.segGapTh_y = 15.0;
lineSegParam.segGapTh_z = 0.0;
filterParam.continuityTh = (number == 1) ? 20.0 : 5.0;
filterParam.outlierTh = 5.0;
growParam.maxLineSkipNum = 2;
growParam.yDeviation_max = 4.0;
growParam.maxSkipDistance = 0.0;
growParam.zDeviation_max = 10.0;
growParam.minLTypeTreeLen = 2.0;
growParam.minVTypeTreeLen = 2.0;
if (number == 3 || number == 4) {
workpieceHoleParam.H = 60.0;
lineSegParam.distScale = 30.0;
lineSegParam.segGapTh_y = 40.0;
} else if (number == 5) {
workpieceHoleParam.holeDiameter = 10.0;
workpieceHoleParam.H = 28.0;
}
}
};
/**
* @brief
*/
struct VrAlgorithmParams
{
2026-07-14 17:14:55 +08:00
VrPlaneCalibParam planeCalibParam; // 全局平面校准参数
std::vector<VrWorkpieceAlgorithmProfile> workpieceProfiles; // 各工件独立算法参数
2026-07-14 17:14:55 +08:00
VrAlgorithmParams()
{
for (int workpieceNumber = 1; workpieceNumber <= 5; ++workpieceNumber) {
workpieceProfiles.push_back(VrWorkpieceAlgorithmProfile(workpieceNumber));
}
}
2026-07-14 17:14:55 +08:00
const VrWorkpieceAlgorithmProfile* FindWorkpieceProfile(int workpieceNumber) const
{
for (unsigned int i = 0; i < workpieceProfiles.size(); ++i) {
if (workpieceProfiles[i].workpieceNumber == workpieceNumber) {
return &workpieceProfiles[i];
}
}
return nullptr;
}
2026-07-14 17:14:55 +08:00
VrWorkpieceAlgorithmProfile* FindWorkpieceProfile(int workpieceNumber)
{
for (unsigned int i = 0; i < workpieceProfiles.size(); ++i) {
if (workpieceProfiles[i].workpieceNumber == workpieceNumber) {
return &workpieceProfiles[i];
}
}
return nullptr;
}
VrWorkpieceAlgorithmProfile& GetOrCreateWorkpieceProfile(int workpieceNumber)
{
VrWorkpieceAlgorithmProfile* profile = FindWorkpieceProfile(workpieceNumber);
if (profile) {
return *profile;
}
workpieceProfiles.push_back(VrWorkpieceAlgorithmProfile(workpieceNumber));
return workpieceProfiles.back();
}
};
/**
* @brief
*/
struct ConfigResult
{
std::vector<DeviceInfo> cameraList;
std::vector<DeviceInfo> deviceList;
VrAlgorithmParams algorithmParams; // 算法参数
std::vector<VrHandEyeCalibMatrix> handEyeCalibMatrixList; // 多相机手眼标定矩阵列表
VrDebugParam debugParam; // 调试参数
SerialConfig serialConfig; // 串口配置
VrPlcRobotServerConfig plcRobotServerConfig; // PLC和机械臂服务端配置
// 显式赋值构造函数,确保正确的深拷贝
ConfigResult& operator=(const ConfigResult& other) {
if (this != &other) {
cameraList = other.cameraList;
deviceList = other.deviceList;
algorithmParams = other.algorithmParams;
handEyeCalibMatrixList = other.handEyeCalibMatrixList;
debugParam = other.debugParam;
serialConfig = other.serialConfig;
plcRobotServerConfig = other.plcRobotServerConfig;
}
return *this;
}
// 显式复制构造函数
ConfigResult(const ConfigResult& other)
: cameraList(other.cameraList)
, deviceList(other.deviceList)
, algorithmParams(other.algorithmParams)
, handEyeCalibMatrixList(other.handEyeCalibMatrixList)
, debugParam(other.debugParam)
, serialConfig(other.serialConfig)
, plcRobotServerConfig(other.plcRobotServerConfig) {
}
// 默认构造函数
ConfigResult() = default;
};
/**
* @brief
*/
enum LoadConfigErrorCode
{
LOAD_CONFIG_SUCCESS = 0, // 加载成功
LOAD_CONFIG_FILE_NOT_FOUND = -1, // 配置文件不存在
LOAD_CONFIG_PARSE_ERROR = -2, // 配置文件解析错误
LOAD_CONFIG_INVALID_FORMAT = -3, // 配置文件格式无效
LOAD_CONFIG_UNKNOWN_ERROR = -99 // 未知错误
};
/**
* @brief VrConfig接口类
*/
class IVrConfig
{
public:
/**
* @brief
*/
virtual ~IVrConfig() {}
/**
* @brief
* @return
*/
static bool CreateInstance(IVrConfig** ppVrConfig);
/**
* @brief
* @param filePath
* @param configResult
* @return (LoadConfigErrorCode): 0=,
*/
virtual int LoadConfig(const std::string& filePath, ConfigResult& configResult) = 0;
/**
* @brief
* @param filePath
* @param configResult
* @return
*/
virtual bool SaveConfig(const std::string& filePath, ConfigResult& configResult) = 0;
/**
* @brief
* @param notify
*/
virtual void SetConfigChangeNotify(IVrConfigChangeNotify* notify) = 0;
};
#endif // IVRCONFIG_H