轮胎检测增加TCP协议
This commit is contained in:
parent
5dc4feab00
commit
1f8cf970be
131
App/WheelMeasure/Doc/TCP_Protocol.md
Normal file
131
App/WheelMeasure/Doc/TCP_Protocol.md
Normal file
@ -0,0 +1,131 @@
|
||||
# 轮眉测量 TCP/IP 通信协议
|
||||
|
||||
## 概述
|
||||
|
||||
- **协议类型**: TCP/IP 文本协议
|
||||
- **默认端口**: 5000(可在配置文件中修改)
|
||||
- **数据格式**: 纯文本,UTF-8编码
|
||||
- **通信模式**: 客户端-服务器模式(视觉系统作为服务器)
|
||||
|
||||
## 协议格式
|
||||
|
||||
### 1. 触发检测命令(客户端 → 服务器)
|
||||
|
||||
```
|
||||
start,100
|
||||
```
|
||||
|
||||
**格式说明**:
|
||||
- `start`: 命令关键字
|
||||
- `100`: 参数(当前未使用,保留用于扩展)
|
||||
|
||||
**示例**:
|
||||
```
|
||||
start,100
|
||||
```
|
||||
|
||||
### 2. 检测结果响应(服务器 → 客户端)
|
||||
|
||||
#### 成功情况(所有相机检测成功)
|
||||
|
||||
```
|
||||
1,100,200;2,100,200;3,100,200;4,100,200
|
||||
```
|
||||
|
||||
**格式说明**:
|
||||
- 多个相机结果用分号 `;` 分隔
|
||||
- 每个相机结果格式:`相机ID,中心点到地面距离,轮眉到地面距离`
|
||||
- `相机ID`: 1-4(对应4个相机)
|
||||
- `中心点到地面距离`: 整数,单位mm
|
||||
- `轮眉到地面距离`: 整数,单位mm
|
||||
|
||||
**示例**:
|
||||
```
|
||||
1,150,250;2,148,252;3,151,249;4,149,251
|
||||
```
|
||||
表示:
|
||||
- 相机1:中心距离150mm,轮眉距离250mm
|
||||
- 相机2:中心距离148mm,轮眉距离252mm
|
||||
- 相机3:中心距离151mm,轮眉距离249mm
|
||||
- 相机4:中心距离149mm,轮眉距离251mm
|
||||
|
||||
#### 失败情况(部分相机检测失败)
|
||||
|
||||
```
|
||||
1,400;2,100,200;3,100,200;4,100,200
|
||||
```
|
||||
|
||||
**错误码说明**:
|
||||
- `400`: 扫描/匹配失败
|
||||
- `401`: 工件为空
|
||||
|
||||
**格式说明**:
|
||||
- 失败的相机只返回:`相机ID,错误码`
|
||||
- 成功的相机返回:`相机ID,中心距离,轮眉距离`
|
||||
|
||||
**示例**:
|
||||
```
|
||||
1,400;2,150,250;3,401;4,149,251
|
||||
```
|
||||
表示:
|
||||
- 相机1:扫描失败(错误码400)
|
||||
- 相机2:成功,中心距离150mm,轮眉距离250mm
|
||||
- 相机3:工件为空(错误码401)
|
||||
- 相机4:成功,中心距离149mm,轮眉距离251mm
|
||||
|
||||
## 通信流程
|
||||
|
||||
```
|
||||
客户端 服务器(视觉系统)
|
||||
| |
|
||||
|-------- start,100 ------------------------>|
|
||||
| |
|
||||
| | 触发所有相机顺序检测
|
||||
| | (相机1 → 相机2 → 相机3 → 相机4)
|
||||
| |
|
||||
|<------- 1,150,250;2,148,252;... -----------|
|
||||
| |
|
||||
```
|
||||
|
||||
**时序说明**:
|
||||
1. 客户端发送 `start,100` 命令
|
||||
2. 服务器收到命令后,依次触发所有启用的相机进行检测
|
||||
3. 所有相机检测完成后,服务器发送汇总结果
|
||||
4. 客户端接收结果并处理
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 连接错误
|
||||
- 如果TCP连接断开,服务器会清除当前客户端的请求状态
|
||||
- 客户端需要重新连接并发送命令
|
||||
|
||||
### 超时处理
|
||||
- 建议客户端设置接收超时(推荐60秒)
|
||||
- 如果超时未收到响应,可以重新发送命令
|
||||
|
||||
### 数据解析
|
||||
- 客户端应验证返回数据格式
|
||||
- 检查相机ID是否在1-4范围内
|
||||
- 检查是否包含错误码(400/401)
|
||||
|
||||
## 配置说明
|
||||
|
||||
TCP服务器端口可在配置文件中修改:
|
||||
|
||||
```xml
|
||||
<ServerList>
|
||||
<Server>
|
||||
<Name>TCPServer</Name>
|
||||
<IP>0.0.0.0</IP>
|
||||
<Port>5000</Port>
|
||||
</Server>
|
||||
</ServerList>
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据单位**:所有距离值单位为毫米(mm)
|
||||
2. **相机顺序**:相机ID固定为1-4,对应配置文件中的相机顺序
|
||||
3. **检测时间**:完整检测所有相机通常需要30-50秒,请设置合理的超时时间
|
||||
4. **并发限制**:服务器同时只处理一个检测请求,多个客户端连接时按先后顺序处理
|
||||
5. **数据精度**:返回的距离值已四舍五入为整数
|
||||
@ -73,8 +73,11 @@ int WheelMeasurePresenter::InitApp()
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化TCP服务器
|
||||
int tcpPort = 6800; // 默认端口
|
||||
// 初始化TCP服务器(从配置读取端口)
|
||||
int tcpPort = 5000; // 默认端口
|
||||
if (!m_configResult.servers.empty()) {
|
||||
tcpPort = m_configResult.servers[0].port;
|
||||
}
|
||||
int tcpResult = m_tcpProtocol.Initialize(tcpPort);
|
||||
if (tcpResult != 0) {
|
||||
LOG_ERROR("Failed to initialize TCP server on port %d, error code: %d\n", tcpPort, tcpResult);
|
||||
@ -306,6 +309,9 @@ void WheelMeasurePresenter::StartAllDetection()
|
||||
|
||||
LOG_INFO("Sequential detection started, total cameras: %d\n", m_sequentialTotalCount);
|
||||
|
||||
|
||||
m_statusUpdate->OnStatusUpdate(QString("开始所有设备的检测"));
|
||||
|
||||
// 开始检测第一个设备
|
||||
continueSequentialDetection();
|
||||
}
|
||||
@ -517,7 +523,7 @@ void WheelMeasurePresenter::processScanData(std::vector<std::pair<EVzResultDataT
|
||||
SSG_lineSegParam lineSegParam;
|
||||
lineSegParam.segGapTh_y = m_configResult.algorithmParams.lineSegParam.segGapTh_y;
|
||||
lineSegParam.segGapTh_z = m_configResult.algorithmParams.lineSegParam.segGapTh_z;
|
||||
lineSegParam.maxDist = m_configResult.algorithmParams.lineSegParam.maxDist;
|
||||
lineSegParam.distScale = m_configResult.algorithmParams.lineSegParam.maxDist;
|
||||
|
||||
SSG_outlierFilterParam filterParam;
|
||||
filterParam.continuityTh = m_configResult.algorithmParams.filterParam.continuityTh;
|
||||
@ -531,7 +537,79 @@ void WheelMeasurePresenter::processScanData(std::vector<std::pair<EVzResultDataT
|
||||
growParam.minLTypeTreeLen = m_configResult.algorithmParams.growParam.minLTypeTreeLen;
|
||||
growParam.minVTypeTreeLen = m_configResult.algorithmParams.growParam.minVTypeTreeLen;
|
||||
|
||||
// 3. 准备调平参数(使用当前相机的调平参数)
|
||||
// 3. 查找当前相机的调平参数(用于后续的ROI检测和调平处理)
|
||||
WheelCameraPlaneCalibParam* calibParam = getPlaneCalibParam(m_currentCameraIndex);
|
||||
|
||||
// 3.5. 调用轮胎存在检测(使用ROI范围过滤)- 在调平处理之前
|
||||
SVzNL3DRangeD wheelRoi3d;
|
||||
if (calibParam) {
|
||||
// 使用当前相机配置的ROI范围
|
||||
wheelRoi3d.xRange.min = calibParam->wheelRoi3d_xMin;
|
||||
wheelRoi3d.xRange.max = calibParam->wheelRoi3d_xMax;
|
||||
wheelRoi3d.yRange.min = calibParam->wheelRoi3d_yMin;
|
||||
wheelRoi3d.yRange.max = calibParam->wheelRoi3d_yMax;
|
||||
wheelRoi3d.zRange.min = calibParam->wheelRoi3d_zMin;
|
||||
wheelRoi3d.zRange.max = calibParam->wheelRoi3d_zMax;
|
||||
|
||||
LOG_INFO("Using ROI range for wheel presence detection:\n");
|
||||
LOG_INFO(" X: [%.1f, %.1f], Y: [%.1f, %.1f], Z: [%.1f, %.1f]\n",
|
||||
wheelRoi3d.xRange.min, wheelRoi3d.xRange.max,
|
||||
wheelRoi3d.yRange.min, wheelRoi3d.yRange.max,
|
||||
wheelRoi3d.zRange.min, wheelRoi3d.zRange.max);
|
||||
} else {
|
||||
// 使用默认ROI范围
|
||||
wheelRoi3d.xRange.min = -1000.0;
|
||||
wheelRoi3d.xRange.max = 1000.0;
|
||||
wheelRoi3d.yRange.min = -1000.0;
|
||||
wheelRoi3d.yRange.max = 1000.0;
|
||||
wheelRoi3d.zRange.min = -1000.0;
|
||||
wheelRoi3d.zRange.max = 1000.0;
|
||||
|
||||
LOG_INFO("Using default ROI range for wheel presence detection: ±1000.0 mm\n");
|
||||
}
|
||||
|
||||
// 调用轮胎存在检测
|
||||
bool wheelPresent = wd_wheelPresenseDetection(scanLines, wheelRoi3d);
|
||||
LOG_INFO("Wheel presence detection result: %s\n", wheelPresent ? "PRESENT" : "NOT PRESENT");
|
||||
|
||||
if (!wheelPresent) {
|
||||
LOG_WARNING("No wheel detected in ROI range, skipping measurement\n");
|
||||
if (m_statusUpdate) {
|
||||
m_statusUpdate->OnStatusUpdate(QString("未检测到轮胎,请检查ROI范围配置"));
|
||||
}
|
||||
|
||||
// 如果是TCP触发的检测,缓存401错误结果
|
||||
if (m_tcpDetectionMode) {
|
||||
WheelMeasureTCPProtocol::CameraMeasureResult tcpResult;
|
||||
tcpResult.cameraId = m_currentCameraIndex;
|
||||
tcpResult.errorCode = 401; // 工件为空
|
||||
tcpResult.centerDistance = 0.0;
|
||||
tcpResult.archDistance = 0.0;
|
||||
m_tcpResults[m_currentCameraIndex] = tcpResult;
|
||||
LOG_INFO("TCP检测结果已缓存: 相机%d, 错误码=401 (未检测到轮胎)\n", m_currentCameraIndex);
|
||||
}
|
||||
|
||||
// 如果正在进行顺序检测,继续检测下一个设备
|
||||
if (m_sequentialDetecting) {
|
||||
m_sequentialCurrentIndex++;
|
||||
|
||||
// TCP模式下,检查是否所有相机都检测完成
|
||||
if (m_tcpDetectionMode && m_tcpResults.size() >= m_sequentialTotalCount) {
|
||||
LOG_INFO("TCP模式:所有相机检测完成,准备发送结果\n");
|
||||
m_sequentialDetecting = false;
|
||||
sendTCPMeasureResults();
|
||||
} else {
|
||||
// 继续检测下一个设备
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
continueSequentialDetection();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 准备调平参数并执行调平处理(使用当前相机的调平参数)
|
||||
SSG_planeCalibPara groundCalibPara;
|
||||
memset(&groundCalibPara, 0, sizeof(groundCalibPara));
|
||||
|
||||
@ -544,8 +622,6 @@ void WheelMeasurePresenter::processScanData(std::vector<std::pair<EVzResultDataT
|
||||
groundCalibPara.invRMatrix[8] = 1.0;
|
||||
groundCalibPara.planeHeight = 0.0;
|
||||
|
||||
// 查找当前相机的调平参数
|
||||
WheelCameraPlaneCalibParam* calibParam = getPlaneCalibParam(m_currentCameraIndex);
|
||||
if (calibParam && calibParam->isCalibrated) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
groundCalibPara.planeCalib[i] = calibParam->planeCalib[i];
|
||||
@ -568,8 +644,7 @@ void WheelMeasurePresenter::processScanData(std::vector<std::pair<EVzResultDataT
|
||||
LOG_WARN("No calibration data for camera %d, using default parameters\n", m_currentCameraIndex);
|
||||
}
|
||||
|
||||
|
||||
// 4. 调用算法
|
||||
// 5. 调用算法
|
||||
int errCode = 0;
|
||||
LOG_INFO("Calling wd_wheelArchHeigthMeasure...\n");
|
||||
|
||||
@ -756,13 +831,19 @@ void WheelMeasurePresenter::processScanData(std::vector<std::pair<EVzResultDataT
|
||||
// 如果正在进行顺序检测,继续检测下一个设备
|
||||
if (m_sequentialDetecting) {
|
||||
m_sequentialCurrentIndex++;
|
||||
|
||||
// TCP模式下,检查是否所有相机都检测完成
|
||||
if (m_tcpDetectionMode && m_tcpResults.size() >= m_sequentialTotalCount) {
|
||||
LOG_INFO("TCP模式:所有相机检测完成,准备发送结果\n");
|
||||
// 先结束顺序检测
|
||||
m_sequentialDetecting = false;
|
||||
// 发送TCP结果
|
||||
sendTCPMeasureResults();
|
||||
} else {
|
||||
// 继续检测下一个设备
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
continueSequentialDetection();
|
||||
}, Qt::QueuedConnection);
|
||||
} else if (m_tcpDetectionMode) {
|
||||
// TCP模式下,检查是否所有相机都检测完成
|
||||
if (m_tcpResults.size() >= m_sequentialTotalCount) {
|
||||
sendTCPMeasureResults();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
#define WHEELMEASURE_VERSION_STRING "1.0.1"
|
||||
#define WHEELMEASURE_BUILD_STRING "5"
|
||||
#define WHEELMEASURE_BUILD_STRING "6"
|
||||
#define WHEELMEASURE_FULL_VERSION_STRING "V" WHEELMEASURE_VERSION_STRING "_" WHEELMEASURE_BUILD_STRING
|
||||
|
||||
// 获取版本信息的便捷函数
|
||||
|
||||
@ -27,6 +27,7 @@ INCLUDEPATH += ../../../Utils/VrCommon/Inc
|
||||
INCLUDEPATH += ../../../AppUtils/UICommon/Inc
|
||||
INCLUDEPATH += ../../../Utils/CloudUtils/Inc
|
||||
INCLUDEPATH += ../../../AppUtils/AppCommon/Inc
|
||||
INCLUDEPATH += ../../../Module/AuthModule/Inc
|
||||
|
||||
INCLUDEPATH += ../../../SDK/Device/VzNLSDK/Inc
|
||||
INCLUDEPATH += ../../../AppAlgo/wheelArchHeigthMeasure/Inc
|
||||
@ -40,6 +41,7 @@ win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../../../AppUtils/UICommon/debug -lUICommon
|
||||
LIBS += -L../../../Utils/CloudUtils/debug -lCloudUtils
|
||||
LIBS += -L../../../AppUtils/AppCommon/debug -lAppCommon
|
||||
LIBS += -L../../../Module/AuthModule/debug -lAuthModule
|
||||
LIBS += -L../../../Module/ModbusTCPServer/debug -lModbusTCPServer
|
||||
LIBS += -L../../../VrNets/debug -lVrModbus
|
||||
} else:win32:CONFIG(release, debug|release) {
|
||||
@ -50,6 +52,7 @@ win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../../../AppUtils/UICommon/release -lUICommon
|
||||
LIBS += -L../../../Utils/CloudUtils/release -lCloudUtils
|
||||
LIBS += -L../../../AppUtils/AppCommon/release -lAppCommon
|
||||
LIBS += -L../../../Module/AuthModule/release -lAuthModule
|
||||
LIBS += -L../../../Module/ModbusTCPServer/release -lModbusTCPServer
|
||||
LIBS += -L../../../VrNets/release -lVrModbus
|
||||
}else:unix:!macx {
|
||||
@ -57,6 +60,7 @@ win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../WheelMeasureConfig -lWheelMeasureConfig
|
||||
LIBS += -L../../../AppUtils/AppCommon -lAppCommon
|
||||
LIBS += -L../../../AppUtils/UICommon -lUICommon
|
||||
LIBS += -L../../../Module/AuthModule -lAuthModule
|
||||
LIBS += -L../../../Utils/CloudUtils -lCloudUtils
|
||||
LIBS += -L../../../Device/VrEyeDevice -lVrEyeDevice
|
||||
LIBS += -L../../../VrNets -lVrTcpClient -lVrTcpServer
|
||||
|
||||
@ -71,6 +71,7 @@ void DialogCameraLevel::setConfig(IVrWheelMeasureConfig* config, WheelMeasureCon
|
||||
// 修复:打开页面时配置可能在相机列表之后设置,导致初始加载失败
|
||||
if (m_currentCameraIndex >= 0 && m_currentCameraIndex < static_cast<int>(m_cameraList.size())) {
|
||||
checkAndDisplayCalibrationStatus(m_currentCameraIndex);
|
||||
loadCameraRoiRange(m_currentCameraIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,6 +615,7 @@ void DialogCameraLevel::on_combo_camera_currentIndexChanged(int index)
|
||||
QString::fromStdString(m_cameraList[index].first).toUtf8().constData());
|
||||
|
||||
checkAndDisplayCalibrationStatus(m_currentCameraIndex);
|
||||
loadCameraRoiRange(m_currentCameraIndex);
|
||||
} else {
|
||||
LOG_WARNING("Invalid camera index selected: %d\n", index);
|
||||
ui->label_level_result->setText("无效的相机选择");
|
||||
@ -703,3 +705,129 @@ void DialogCameraLevel::on_btn_save_compensation_clicked()
|
||||
LOG_ERROR("Failed to save error compensation\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DialogCameraLevel::loadCameraRoiRange(int cameraIndex)
|
||||
{
|
||||
if (!m_pConfig || !m_pConfigResult) {
|
||||
LOG_WARNING("Config is null, cannot load ROI range\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cameraIndex < 0 || cameraIndex >= static_cast<int>(m_cameraList.size())) {
|
||||
LOG_WARNING("Invalid camera index: %d\n", cameraIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
int configCameraIndex = cameraIndex + 1; // 转换为1-based索引
|
||||
|
||||
// 查找相机的调平参数
|
||||
for (const auto& param : m_pConfigResult->planeCalibParams) {
|
||||
if (param.cameraIndex == configCameraIndex) {
|
||||
// 加载ROI范围到UI
|
||||
ui->edit_roi_x_min->setText(QString::number(param.wheelRoi3d_xMin, 'f', 1));
|
||||
ui->edit_roi_x_max->setText(QString::number(param.wheelRoi3d_xMax, 'f', 1));
|
||||
ui->edit_roi_y_min->setText(QString::number(param.wheelRoi3d_yMin, 'f', 1));
|
||||
ui->edit_roi_y_max->setText(QString::number(param.wheelRoi3d_yMax, 'f', 1));
|
||||
ui->edit_roi_z_min->setText(QString::number(param.wheelRoi3d_zMin, 'f', 1));
|
||||
ui->edit_roi_z_max->setText(QString::number(param.wheelRoi3d_zMax, 'f', 1));
|
||||
|
||||
LOG_INFO("Loaded ROI range for camera %d: X[%.1f, %.1f], Y[%.1f, %.1f], Z[%.1f, %.1f]\n",
|
||||
configCameraIndex,
|
||||
param.wheelRoi3d_xMin, param.wheelRoi3d_xMax,
|
||||
param.wheelRoi3d_yMin, param.wheelRoi3d_yMax,
|
||||
param.wheelRoi3d_zMin, param.wheelRoi3d_zMax);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到,使用默认值
|
||||
ui->edit_roi_x_min->setText("-1000.0");
|
||||
ui->edit_roi_x_max->setText("1000.0");
|
||||
ui->edit_roi_y_min->setText("-1000.0");
|
||||
ui->edit_roi_y_max->setText("1000.0");
|
||||
ui->edit_roi_z_min->setText("-1000.0");
|
||||
ui->edit_roi_z_max->setText("1000.0");
|
||||
LOG_INFO("No ROI range found for camera %d, using default values\n", configCameraIndex);
|
||||
}
|
||||
|
||||
void DialogCameraLevel::saveCameraRoiRange()
|
||||
{
|
||||
if (!m_pConfig || !m_pConfigResult) {
|
||||
LOG_ERROR("Config is null, cannot save ROI range\n");
|
||||
QMessageBox::warning(this, "错误", "配置对象为空,无法保存ROI范围");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_currentCameraIndex < 0 || m_currentCameraIndex >= static_cast<int>(m_cameraList.size())) {
|
||||
LOG_WARNING("Invalid camera index: %d\n", m_currentCameraIndex);
|
||||
QMessageBox::warning(this, "错误", "请先选择相机");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取UI中的ROI范围值
|
||||
double xMin = ui->edit_roi_x_min->text().toDouble();
|
||||
double xMax = ui->edit_roi_x_max->text().toDouble();
|
||||
double yMin = ui->edit_roi_y_min->text().toDouble();
|
||||
double yMax = ui->edit_roi_y_max->text().toDouble();
|
||||
double zMin = ui->edit_roi_z_min->text().toDouble();
|
||||
double zMax = ui->edit_roi_z_max->text().toDouble();
|
||||
|
||||
// 验证范围有效性
|
||||
if (xMin >= xMax || yMin >= yMax || zMin >= zMax) {
|
||||
QMessageBox::warning(this, "错误", "ROI范围无效:最小值必须小于最大值");
|
||||
return;
|
||||
}
|
||||
|
||||
int cameraIndex = m_currentCameraIndex + 1; // 转换为1-based索引
|
||||
QString cameraName = QString::fromStdString(m_cameraList[m_currentCameraIndex].first);
|
||||
|
||||
LOG_INFO("Saving ROI range for camera %d (%s): X[%.1f, %.1f], Y[%.1f, %.1f], Z[%.1f, %.1f]\n",
|
||||
cameraIndex, cameraName.toUtf8().constData(),
|
||||
xMin, xMax, yMin, yMax, zMin, zMax);
|
||||
|
||||
// 查找或创建相机调平参数
|
||||
bool found = false;
|
||||
for (auto& param : m_pConfigResult->planeCalibParams) {
|
||||
if (param.cameraIndex == cameraIndex) {
|
||||
param.wheelRoi3d_xMin = xMin;
|
||||
param.wheelRoi3d_xMax = xMax;
|
||||
param.wheelRoi3d_yMin = yMin;
|
||||
param.wheelRoi3d_yMax = yMax;
|
||||
param.wheelRoi3d_zMin = zMin;
|
||||
param.wheelRoi3d_zMax = zMax;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到现有记录,创建一个新的
|
||||
if (!found) {
|
||||
WheelCameraPlaneCalibParam newParam;
|
||||
newParam.cameraIndex = cameraIndex;
|
||||
newParam.cameraName = cameraName.toStdString();
|
||||
newParam.wheelRoi3d_xMin = xMin;
|
||||
newParam.wheelRoi3d_xMax = xMax;
|
||||
newParam.wheelRoi3d_yMin = yMin;
|
||||
newParam.wheelRoi3d_yMax = yMax;
|
||||
newParam.wheelRoi3d_zMin = zMin;
|
||||
newParam.wheelRoi3d_zMax = zMax;
|
||||
newParam.isCalibrated = false; // 尚未标定
|
||||
m_pConfigResult->planeCalibParams.push_back(newParam);
|
||||
}
|
||||
|
||||
// 保存配置到文件
|
||||
QString configPath = PathManager::GetInstance().GetConfigFilePath();
|
||||
bool saveResult = m_pConfig->SaveConfig(configPath.toStdString(), *m_pConfigResult);
|
||||
if (saveResult) {
|
||||
LOG_INFO("ROI range saved successfully for camera %d\n", cameraIndex);
|
||||
QMessageBox::information(this, "成功", "ROI范围已保存");
|
||||
} else {
|
||||
LOG_ERROR("Failed to save ROI range\n");
|
||||
QMessageBox::critical(this, "错误", "保存ROI范围失败");
|
||||
}
|
||||
}
|
||||
|
||||
void DialogCameraLevel::on_btn_save_roi_clicked()
|
||||
{
|
||||
saveCameraRoiRange();
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@ private slots:
|
||||
void on_btn_cancel_clicked();
|
||||
void on_combo_camera_currentIndexChanged(int index);
|
||||
void on_btn_save_compensation_clicked();
|
||||
void on_btn_save_roi_clicked();
|
||||
|
||||
private:
|
||||
Ui::DialogCameraLevel *ui;
|
||||
@ -113,6 +114,10 @@ private:
|
||||
|
||||
// 检查并显示相机标定状态
|
||||
void checkAndDisplayCalibrationStatus(int cameraIndex);
|
||||
|
||||
// 加载和保存ROI范围
|
||||
void loadCameraRoiRange(int cameraIndex);
|
||||
void saveCameraRoiRange();
|
||||
};
|
||||
|
||||
#endif // DIALOGCAMERALEVEL_H
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>659</width>
|
||||
<height>453</height>
|
||||
<height>599</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -65,7 +65,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>170</x>
|
||||
<y>400</y>
|
||||
<y>550</y>
|
||||
<width>101</width>
|
||||
<height>38</height>
|
||||
</rect>
|
||||
@ -86,7 +86,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>380</x>
|
||||
<y>400</y>
|
||||
<y>550</y>
|
||||
<width>111</width>
|
||||
<height>38</height>
|
||||
</rect>
|
||||
@ -300,6 +300,454 @@ QPushButton:pressed {
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_roi">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>390</y>
|
||||
<width>621</width>
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QGroupBox {
|
||||
color: rgb(221, 225, 233);
|
||||
border: 1px solid #3B3D47;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
padding: 0 5px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>轮胎存在检测ROI范围 (mm)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_roi">
|
||||
<property name="leftMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_to_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>~</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="edit_roi_z_min">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-1000.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="btn_save_roi">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>35</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>35</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
color: rgb(221, 225, 233);
|
||||
background-color: rgb(60, 63, 65);
|
||||
border: 1px solid #3B3D47;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgb(80, 83, 85);
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: rgb(45, 48, 50);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="edit_roi_z_max">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>500.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_x_range">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>X范围:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_z_range">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Z范围:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="edit_roi_x_min">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-500.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_to_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>~</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_to_1">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>~</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="edit_roi_y_max">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1000.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="edit_roi_x_max">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1000.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="edit_roi_y_min">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-1000.0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_y_range">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Y范围:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="3">
|
||||
<spacer name="horizontalSpacer_roi">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "IWheelMeasureStatus.h"
|
||||
#include "IVrWheelMeasureConfig.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "AuthView.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMetaType>
|
||||
@ -69,6 +70,12 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 检查授权,无授权则显示授权对话框
|
||||
if (!AuthView::CheckAndShow(nullptr)) {
|
||||
// 用户取消授权或授权失败,退出程序
|
||||
return 0;
|
||||
}
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
|
||||
@ -531,6 +531,8 @@ void MainWindow::OnDeviceStatusChanged(const QString &deviceName, int deviceStat
|
||||
|
||||
void MainWindow::OnClearMeasureData()
|
||||
{
|
||||
if (m_logHelper) m_logHelper->clearLog();
|
||||
|
||||
if (m_measureResultWidget) {
|
||||
m_measureResultWidget->clearAllResults();
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ struct WheelServerInfo
|
||||
{
|
||||
std::string name; // 服务器名称
|
||||
std::string ip; // 服务器IP地址
|
||||
int port = 5800; // 服务器端口
|
||||
int port = 5000; // 服务器端口
|
||||
};
|
||||
|
||||
/**
|
||||
@ -62,6 +62,14 @@ struct WheelCameraPlaneCalibParam
|
||||
double invRMatrix[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; // 逆旋转矩阵(回到原坐标系)
|
||||
bool isCalibrated = false; // 是否已标定
|
||||
double errorCompensation = -5.0; // 误差补偿(mm)
|
||||
|
||||
// 轮胎存在检测的3D ROI范围
|
||||
double wheelRoi3d_xMin = -1000.0; // X方向最小值(mm)
|
||||
double wheelRoi3d_xMax = 1000.0; // X方向最大值(mm)
|
||||
double wheelRoi3d_yMin = -1000.0; // Y方向最小值(mm)
|
||||
double wheelRoi3d_yMax = 1000.0; // Y方向最大值(mm)
|
||||
double wheelRoi3d_zMin = -1000.0; // Z方向最小值(mm)
|
||||
double wheelRoi3d_zMax = 1000.0; // Z方向最大值(mm)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -168,6 +176,8 @@ struct WheelMeasureResult
|
||||
QImage image; // 图像
|
||||
bool bImageValid = false; // 图像是否有效
|
||||
bool bResultValid = false; // 结果是否有效
|
||||
int errorCode = 0; // 错误码(0表示成功,401表示工件为空)
|
||||
QString errorMessage = ""; // 错误信息
|
||||
std::vector<WheelMeasureData> result; // 测量结果列表
|
||||
};
|
||||
|
||||
|
||||
@ -91,6 +91,24 @@ WheelMeasureConfigResult VrWheelMeasureConfig::LoadConfig(const std::string& fil
|
||||
calibParam.errorCompensation = -5.0;
|
||||
}
|
||||
|
||||
// 读取轮胎存在检测的3D ROI范围
|
||||
if (xml.attributes().hasAttribute("wheelRoi3d_xMin")) {
|
||||
calibParam.wheelRoi3d_xMin = xml.attributes().value("wheelRoi3d_xMin").toDouble();
|
||||
calibParam.wheelRoi3d_xMax = xml.attributes().value("wheelRoi3d_xMax").toDouble();
|
||||
calibParam.wheelRoi3d_yMin = xml.attributes().value("wheelRoi3d_yMin").toDouble();
|
||||
calibParam.wheelRoi3d_yMax = xml.attributes().value("wheelRoi3d_yMax").toDouble();
|
||||
calibParam.wheelRoi3d_zMin = xml.attributes().value("wheelRoi3d_zMin").toDouble();
|
||||
calibParam.wheelRoi3d_zMax = xml.attributes().value("wheelRoi3d_zMax").toDouble();
|
||||
} else {
|
||||
// 默认值
|
||||
calibParam.wheelRoi3d_xMin = -1000.0;
|
||||
calibParam.wheelRoi3d_xMax = 1000.0;
|
||||
calibParam.wheelRoi3d_yMin = -1000.0;
|
||||
calibParam.wheelRoi3d_yMax = 1000.0;
|
||||
calibParam.wheelRoi3d_zMin = -1000.0;
|
||||
calibParam.wheelRoi3d_zMax = 1000.0;
|
||||
}
|
||||
|
||||
// 读取planeCalib矩阵
|
||||
QString planeCalibStr = xml.attributes().value("planeCalib").toString();
|
||||
QStringList planeCalibList = planeCalibStr.split(",");
|
||||
@ -330,6 +348,14 @@ bool VrWheelMeasureConfig::SaveConfig(const std::string& filePath, WheelMeasureC
|
||||
xml.writeAttribute("isCalibrated", QString::number(calibParam.isCalibrated ? 1 : 0));
|
||||
xml.writeAttribute("errorCompensation", QString::number(calibParam.errorCompensation, 'f', 2));
|
||||
|
||||
// 保存轮胎存在检测的3D ROI范围
|
||||
xml.writeAttribute("wheelRoi3d_xMin", QString::number(calibParam.wheelRoi3d_xMin, 'f', 2));
|
||||
xml.writeAttribute("wheelRoi3d_xMax", QString::number(calibParam.wheelRoi3d_xMax, 'f', 2));
|
||||
xml.writeAttribute("wheelRoi3d_yMin", QString::number(calibParam.wheelRoi3d_yMin, 'f', 2));
|
||||
xml.writeAttribute("wheelRoi3d_yMax", QString::number(calibParam.wheelRoi3d_yMax, 'f', 2));
|
||||
xml.writeAttribute("wheelRoi3d_zMin", QString::number(calibParam.wheelRoi3d_zMin, 'f', 2));
|
||||
xml.writeAttribute("wheelRoi3d_zMax", QString::number(calibParam.wheelRoi3d_zMax, 'f', 2));
|
||||
|
||||
// 保存planeCalib矩阵
|
||||
QStringList planeCalibList;
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -25,6 +25,26 @@ typedef struct
|
||||
double yawAngle; //偏转角:绕Z轴的偏转, 弧度
|
||||
}SSG_6AxisAttitude;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
}SWD3DPoint;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int lineIdx;
|
||||
int ptIdx;
|
||||
SWD3DPoint point;
|
||||
}SWDIndexing3DPoint;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int start;
|
||||
int end;
|
||||
}SWD_Interval; //区间
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool validFlag; //指示结果是否有效
|
||||
@ -41,6 +61,12 @@ typedef enum
|
||||
keSG_PoseSorting_T2B_L2R, ///从上到下,从左到右排序
|
||||
} ESG_poseSortingMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KeWD_Mask_ValidPt = 0,
|
||||
KeWD_Mask_NullPt,
|
||||
}EWD_maskMode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int data_0;
|
||||
@ -48,6 +74,13 @@ typedef struct
|
||||
int idx;
|
||||
}SSG_intPair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flag;
|
||||
int validFlag;
|
||||
int clusterID;
|
||||
}SSG_clusterLabel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int featurType;
|
||||
@ -67,6 +100,18 @@ typedef struct
|
||||
double bottom;
|
||||
}SSG_ROIRectD;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double width;
|
||||
double height;
|
||||
}SSG_size2D;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SVzNL3DPoint center;
|
||||
double radius;
|
||||
}SWD_HoleInfo;
|
||||
|
||||
struct HSV {
|
||||
double h; // 色相 (0-360)
|
||||
double s; // 饱和度 (0-1)
|
||||
@ -172,9 +217,16 @@ typedef struct
|
||||
{
|
||||
double segGapTh_y; //y方向连续段门限。大于此门限,为不连续
|
||||
double segGapTh_z; //z方向连续段门限。大于此门限,为不连续
|
||||
double maxDist; //计算方向角的窗口比例尺
|
||||
double distScale; //计算方向角的窗口比例尺
|
||||
}SSG_lineSegParam;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double minJumpZ; //z方向跳变门限
|
||||
double minK; //跳变的最小斜率
|
||||
SVzNLRangeD widthRange; //z方向连续段门限。大于此门限,为不连续
|
||||
}SSG_raisedFeatureParam;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double scale_angle; //计算方向角的窗口比例尺
|
||||
@ -202,6 +254,7 @@ typedef struct
|
||||
int endPtIdx;
|
||||
SVzNL3DPoint startPt;
|
||||
SVzNL3DPoint endPt;
|
||||
double featureValue;
|
||||
}SWD_segFeature;
|
||||
|
||||
typedef struct
|
||||
@ -394,9 +447,9 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SVzNL3DPoint opCenter; //定子中心位置
|
||||
double objR;
|
||||
}SWD_motorStatorPosition;
|
||||
int objID;
|
||||
SSG_6DOF opCenter; //定子中心位置
|
||||
}SWD_statorInnerGrasper;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -479,6 +532,20 @@ typedef struct
|
||||
double invRMatrix[9]; //旋转矩阵,回到原坐标系
|
||||
}SSG_planeCalibPara;
|
||||
|
||||
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 pntIdx;
|
||||
@ -494,6 +561,18 @@ typedef struct
|
||||
double backward_z;
|
||||
}SSG_pntDirAngle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double forwardAngle; //前向角
|
||||
double backwardAngle; //后向角
|
||||
double corner; //拐角
|
||||
int pntIdx;
|
||||
int forward_pntIdx;
|
||||
int backward_pntIdx;
|
||||
int flag;
|
||||
SWD_polarPt point;
|
||||
}SSG_dirCornerAngle;
|
||||
|
||||
// 图像数据结构
|
||||
typedef struct {
|
||||
int width;
|
||||
@ -515,20 +594,6 @@ typedef struct
|
||||
SVzNL3DPoint pt2;
|
||||
}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;
|
||||
@ -536,6 +601,8 @@ typedef struct
|
||||
int L2_ptIndex;
|
||||
double cornerAngle;
|
||||
int cornerDir;
|
||||
int flag;
|
||||
SWD_polarPt point;
|
||||
}SWD_polarPeakInfo;
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
#define SG_ERR_LABEL_INFO_ERROR -1004
|
||||
#define SG_ERR_INVLD_SORTING_MODE -1005
|
||||
#define SG_ERR_INVLD_Q_SCALE -1006
|
||||
#define SG_ERR_ZERO_OBJECTS -1007
|
||||
#define SG_ERR_LASER_DIR_NOT_SUPPORTED -1008
|
||||
#define SG_ERR_SCAN_DIR_NOT_SUPPORTED -1009
|
||||
|
||||
//BQ_workpiece
|
||||
#define SX_ERR_INVLD_VTREE_NUM -2001
|
||||
@ -20,7 +23,9 @@
|
||||
|
||||
//定子抓取
|
||||
#define SX_ERR_INVLID_CUTTING_Z -2101
|
||||
#define SX_ERR_ZERO_OBJ -2102
|
||||
#define SX_ERR_ZERO_OBJ_TOPLAYER -2102
|
||||
#define SX_ERR_ZERO_OBJ_BTMLAYER -2103
|
||||
#define SX_ERR_GET_INVALID_PALTE -2104 //¸ô°åÌáÈ¡´íÎó
|
||||
|
||||
//拆包
|
||||
#define SX_BAG_TRAY_EMPTY -2201
|
||||
@ -28,3 +33,6 @@
|
||||
//汽车轮眉高度测量
|
||||
#define SX_ERR_INVALID_ARC -2301
|
||||
|
||||
//ÌÇ´ü×Ó²ðÏß
|
||||
#define SX_ERR_NO_MARK -2401
|
||||
|
||||
|
||||
@ -33,6 +33,11 @@ SG_APISHARED_EXPORT void wd_horizonCamera_lineDataR(
|
||||
const double* camPoseR,
|
||||
double groundH);
|
||||
|
||||
//相机水平时姿态调平,并去除地面
|
||||
SG_APISHARED_EXPORT bool wd_wheelPresenseDetection(
|
||||
std::vector<std::vector< SVzNL3DPosition>>& scanLine,
|
||||
const SVzNL3DRangeD wheelRoi3d);
|
||||
|
||||
//提取工件角点及定位长度信息
|
||||
SG_APISHARED_EXPORT WD_wheelArchInfo wd_wheelArchHeigthMeasure(
|
||||
std::vector< std::vector<SVzNL3DPosition>>& scanLines,
|
||||
|
||||
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.
@ -2637,7 +2637,7 @@ void _outputScanDataFile_removeZeros(char* fileName, SVzNL3DLaserLine * scanData
|
||||
|
||||
#define TEST_CONVERT_TO_GRID 0
|
||||
#define TEST_COMPUTE_WHEEL_ARCH 1
|
||||
#define TEST_COMPUTE_CALIB_PARA 0
|
||||
#define TEST_COMPUTE_CALIB_PARA 1
|
||||
|
||||
#define TEST_GROUP 1
|
||||
int main()
|
||||
@ -2683,7 +2683,7 @@ int main()
|
||||
|
||||
#if TEST_COMPUTE_CALIB_PARA
|
||||
char _calib_datafile[256];
|
||||
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/LaserLine1_grid.txt");
|
||||
sprintf_s(_calib_datafile, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/现场数据/ground_LaserData.txt");
|
||||
|
||||
std::vector< std::vector<SVzNL3DPosition>> scanLines;
|
||||
vzReadLaserScanPointFromFile_XYZ_vector(_calib_datafile, scanLines);
|
||||
@ -2704,10 +2704,10 @@ int main()
|
||||
#endif
|
||||
//
|
||||
char calibFile[250];
|
||||
sprintf_s(calibFile, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/ground_calib_para.txt");
|
||||
sprintf_s(calibFile, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/现场数据/ground_calib_para.txt");
|
||||
_outputCalibPara(calibFile, calibPara);
|
||||
char _out_file[256];
|
||||
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/LaserLine1_grid_calib.txt");
|
||||
sprintf_s(_out_file, "F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/现场数据/LaserLine_grund_calib.txt");
|
||||
_outputScanDataFile_self(_out_file, scanLines, 0, 0, 0);
|
||||
printf("%s: calib done!\n", _calib_datafile);
|
||||
}
|
||||
@ -2716,11 +2716,11 @@ int main()
|
||||
|
||||
#if TEST_COMPUTE_WHEEL_ARCH
|
||||
const char* dataPath[TEST_GROUP] = {
|
||||
"F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/", //0
|
||||
"F:/ShangGu/项目/冠钦_轮眉高度测量/测试数据/现场数据/", //0
|
||||
};
|
||||
|
||||
SVzNLRange fileIdx[TEST_GROUP] = {
|
||||
{1,1},
|
||||
{1,2},
|
||||
};
|
||||
|
||||
SSG_planeCalibPara poseCalibPara;
|
||||
@ -2752,7 +2752,7 @@ int main()
|
||||
for (int fidx = fileIdx[grp].nMin; fidx <= fileIdx[grp].nMax; fidx++)
|
||||
{
|
||||
//fidx = 193;
|
||||
sprintf_s(_scan_file, "%sLaserLine1_grid.txt", dataPath[grp], fidx);
|
||||
sprintf_s(_scan_file, "%sLaserData_%d.txt", dataPath[grp], fidx);
|
||||
std::vector<std::vector< SVzNL3DPosition>> scanData;
|
||||
vzReadLaserScanPointFromFile_XYZ_vector(_scan_file, scanData);
|
||||
if (scanData.size() == 0)
|
||||
@ -2762,21 +2762,10 @@ int main()
|
||||
//algoParam.filterParam.outlierTh = 5;
|
||||
|
||||
long t1 = GetTickCount64();
|
||||
int lineNum = (int)scanData.size();
|
||||
for (int i = 0; i < lineNum; i++)
|
||||
{
|
||||
if (i == 14)
|
||||
int kkk = 1;
|
||||
//行处理
|
||||
//调平,去除地面
|
||||
wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight);
|
||||
}
|
||||
#if 0 //数据转存
|
||||
sprintf_s(_scan_file, "%sLaserLine%d_grid_RTadjust.txt", dataPath[grp], fidx);
|
||||
_outputScanDataFile_self(_scan_file, scanData, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
SVzNL3DRangeD wheelRoi3d = { {-1000, 1000}, {-2000, 2000}, {500, 2500} };
|
||||
SSG_cornerParam cornerParam;
|
||||
cornerParam.cornerTh = 60; //45度角
|
||||
cornerParam.cornerTh = 45; //45度角
|
||||
cornerParam.scale = 50; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||||
cornerParam.minEndingGap = 20; // algoParam.bagParam.bagW / 4;
|
||||
cornerParam.minEndingGap_z = 20;
|
||||
@ -2784,7 +2773,7 @@ int main()
|
||||
cornerParam.jumpCornerTh_2 = 60;
|
||||
|
||||
SSG_lineSegParam lineSegPara;
|
||||
lineSegPara.maxDist = 1.0;
|
||||
lineSegPara.distScale = 1.0;
|
||||
lineSegPara.segGapTh_y = 5.0; //y方向间隔大于5mm认为是分段
|
||||
lineSegPara.segGapTh_z = 10.0; //z方向间隔大于10mm认为是分段
|
||||
|
||||
@ -2800,6 +2789,27 @@ int main()
|
||||
growParam.minLTypeTreeLen = 100; //mm
|
||||
growParam.minVTypeTreeLen = 100; //mm
|
||||
|
||||
WD_wheelArchInfo wheelArcHeight;
|
||||
memset(&wheelArcHeight, 0, sizeof(WD_wheelArchInfo));
|
||||
|
||||
bool wheePresense = wd_wheelPresenseDetection( scanData, wheelRoi3d);
|
||||
if (true == wheePresense)
|
||||
{
|
||||
int lineNum = (int)scanData.size();
|
||||
for (int i = 0; i < lineNum; i++)
|
||||
{
|
||||
if (i == 14)
|
||||
int kkk = 1;
|
||||
//行处理
|
||||
//调平,去除地面
|
||||
wd_horizonCamera_lineDataR(scanData[i], poseCalibPara.planeCalib, poseCalibPara.planeHeight - 5);
|
||||
}
|
||||
#if 0 //数据转存
|
||||
sprintf_s(_scan_file, "%sLaserLine%d_grid_RTadjust.txt", dataPath[grp], fidx);
|
||||
_outputScanDataFile_self(_scan_file, scanData, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
|
||||
int errCode = 0;
|
||||
WD_wheelArchInfo wheelArcHeight = wd_wheelArchHeigthMeasure(
|
||||
scanData,
|
||||
@ -2809,20 +2819,20 @@ int main()
|
||||
growParam,
|
||||
poseCalibPara,
|
||||
&errCode);
|
||||
#endif
|
||||
}
|
||||
long t2 = GetTickCount64();
|
||||
|
||||
|
||||
char _dbg_file[256];
|
||||
#if 1
|
||||
|
||||
sprintf_s(_dbg_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
|
||||
_outputScanDataFile_RGBD_obj(_dbg_file, scanData, 0, 0, 0, wheelArcHeight);
|
||||
#endif
|
||||
printf("%s: height=%f, %d(ms)!\n", _scan_file, wheelArcHeight.archToCenterHeigth, (int)(t2 - t1));
|
||||
|
||||
|
||||
printf("%s: height=%f, arcToGrund=%f, time=%d(ms)!\n", _scan_file, wheelArcHeight.archToCenterHeigth, wheelArcHeight.archToGroundHeigth, (int)(t2 - t1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("all done!\n");
|
||||
}
|
||||
|
||||
|
||||
@ -65,6 +65,12 @@ echo "复制 Qt 运行时环境..."
|
||||
cp -rfd ${QT_PKG_PATH}/ext ${PKG_PATH}/opt/firefly_qt5.15
|
||||
cp ${QT_PKG_PATH}/target_qtEnv.sh ${PKG_PATH}/etc/profile.d/
|
||||
|
||||
echo "清理不需要的 Qt WebEngine 库文件..."
|
||||
rm -f ${PKG_PATH}/opt/firefly_qt5.15/lib/libQt5WebEngine*
|
||||
rm -rf ${PKG_PATH}/opt/firefly_qt5.15/libexec/QtWebEngineProcess
|
||||
rm -rf ${PKG_PATH}/opt/firefly_qt5.15/resources/qtwebengine*
|
||||
rm -rf ${PKG_PATH}/opt/firefly_qt5.15/translations/qtwebengine*
|
||||
|
||||
# 复制 Qt 库文件
|
||||
for libfile in ${QT_LIB_PATH}/*.so*; do
|
||||
# 获取文件名用于比较
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user