皮带撕裂结果合并
This commit is contained in:
parent
74a3e72534
commit
3932ec324d
@ -62,16 +62,16 @@ struct TearingData
|
|||||||
|
|
||||||
static TearingData fromJsonObject(const QJsonObject &json) {
|
static TearingData fromJsonObject(const QJsonObject &json) {
|
||||||
TearingData data;
|
TearingData data;
|
||||||
data.level = json["level"].toString();
|
data.level = json["level"].toString();
|
||||||
data.id = json["id"].toString();
|
data.id = json["id"].toString();
|
||||||
data.tearStatus = json["tearStatus"].toString();
|
data.tearStatus = json["tearStatus"].toString();
|
||||||
data.tearType = json["tearType"].toString();
|
data.tearType = json["tearType"].toString();
|
||||||
data.statLineIdx = json["statLineIdx"].toString();
|
data.statLineIdx = json["statLineIdx"].toString();
|
||||||
data.endLineIdx = json["endLineIdx"].toString();
|
data.endLineIdx = json["endLineIdx"].toString();
|
||||||
data.tearDepth = json["tearDepth"].toString();
|
data.tearDepth = json["tearDepth"].toString();
|
||||||
data.tearWidth = json["tearWidth"].toString();
|
data.tearWidth = json["tearWidth"].toString();
|
||||||
data.tearLength = json["tearLength"].toString();
|
data.tearLength = json["tearLength"].toString();
|
||||||
data.older = json["older"].toString();
|
data.older = json["older"].toString();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -290,9 +290,6 @@ void BeltTearingPresenter::handleTcpDataReceived(const QString &serverName, cons
|
|||||||
// 将新数据添加到缓存
|
// 将新数据添加到缓存
|
||||||
m_dataBuffers[serverName].append(pData, nLen);
|
m_dataBuffers[serverName].append(pData, nLen);
|
||||||
|
|
||||||
LOG_DEBUG("Buffered data for %s: buffer_size=%d, new_data=%d\n",
|
|
||||||
serverName.toStdString().c_str(), m_dataBuffers[serverName].size(), nLen);
|
|
||||||
|
|
||||||
// 检查是否有完整的数据包
|
// 检查是否有完整的数据包
|
||||||
QByteArray &buffer = m_dataBuffers[serverName];
|
QByteArray &buffer = m_dataBuffers[serverName];
|
||||||
const QByteArray endMarker = "___END___\r\n";
|
const QByteArray endMarker = "___END___\r\n";
|
||||||
@ -301,8 +298,7 @@ void BeltTearingPresenter::handleTcpDataReceived(const QString &serverName, cons
|
|||||||
while (endPos != -1) {
|
while (endPos != -1) {
|
||||||
// 找到完整数据包
|
// 找到完整数据包
|
||||||
QByteArray completePacket = buffer.left(endPos);
|
QByteArray completePacket = buffer.left(endPos);
|
||||||
LOG_DEBUG("Found complete packet for %s: size=%d\n",
|
// LOG_DEBUG("Found complete packet for %s: size=%d\n", serverName.toStdString().c_str(), completePacket.size());
|
||||||
serverName.toStdString().c_str(), completePacket.size());
|
|
||||||
|
|
||||||
// 处理完整数据包
|
// 处理完整数据包
|
||||||
processCompletePacket(serverName, completePacket);
|
processCompletePacket(serverName, completePacket);
|
||||||
@ -323,8 +319,7 @@ void BeltTearingPresenter::handleTcpDataReceived(const QString &serverName, cons
|
|||||||
|
|
||||||
void BeltTearingPresenter::processCompletePacket(const QString &serverName, const QByteArray &completeData)
|
void BeltTearingPresenter::processCompletePacket(const QString &serverName, const QByteArray &completeData)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Processing complete packet from %s: size=%d\n",
|
// LOG_DEBUG("Processing complete packet from %s: size=%d\n", serverName.toStdString().c_str(), completeData.size());
|
||||||
serverName.toStdString().c_str(), completeData.size());
|
|
||||||
|
|
||||||
// 解析数据包协议头
|
// 解析数据包协议头
|
||||||
if (completeData.size() < 5) {
|
if (completeData.size() < 5) {
|
||||||
@ -347,8 +342,7 @@ void BeltTearingPresenter::processCompletePacket(const QString &serverName, cons
|
|||||||
|
|
||||||
QByteArray payloadData = completeData.mid(5, dataSize);
|
QByteArray payloadData = completeData.mid(5, dataSize);
|
||||||
|
|
||||||
LOG_DEBUG("Parsed packet: dataType=%d, dataSize=%d, payload_size=%d\n",
|
// LOG_DEBUG("Parsed packet: dataType=%d, dataSize=%d, payload_size=%d\n", dataType, dataSize, payloadData.size());
|
||||||
dataType, dataSize, payloadData.size());
|
|
||||||
|
|
||||||
BeltTearingResult tearResult;
|
BeltTearingResult tearResult;
|
||||||
tearResult.bImageValid = false;
|
tearResult.bImageValid = false;
|
||||||
@ -357,7 +351,6 @@ void BeltTearingPresenter::processCompletePacket(const QString &serverName, cons
|
|||||||
{
|
{
|
||||||
// 处理文本数据
|
// 处理文本数据
|
||||||
QString textData = QString::fromUtf8(payloadData);
|
QString textData = QString::fromUtf8(payloadData);
|
||||||
LOG_DEBUG("Received text data: %s\n", textData.left(100).toStdString().c_str());
|
|
||||||
|
|
||||||
// 解析JSON数据
|
// 解析JSON数据
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(textData.toUtf8());
|
QJsonDocument doc = QJsonDocument::fromJson(textData.toUtf8());
|
||||||
@ -380,16 +373,12 @@ void BeltTearingPresenter::processCompletePacket(const QString &serverName, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Processed text data from server %s\n", serverName.toStdString().c_str());
|
|
||||||
}
|
}
|
||||||
else if (dataType == static_cast<int>(ByteDataType::Image))
|
else if (dataType == static_cast<int>(ByteDataType::Image))
|
||||||
{
|
{
|
||||||
// 处理图像数据
|
// 处理图像数据
|
||||||
LOG_DEBUG("Attempting to load image from %d bytes\n", payloadData.size());
|
|
||||||
if (tearResult.image.loadFromData(payloadData)) {
|
if (tearResult.image.loadFromData(payloadData)) {
|
||||||
tearResult.bImageValid = true;
|
tearResult.bImageValid = true;
|
||||||
LOG_DEBUG("Successfully loaded image: %dx%d\n",
|
|
||||||
tearResult.image.width(), tearResult.image.height());
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Failed to load image from data\n");
|
LOG_ERROR("Failed to load image from data\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QList>
|
||||||
|
#include <QPersistentModelIndex>
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
// Register meta types for signal-slot connections
|
||||||
|
qRegisterMetaType<QVector<int>>("QVector<int>");
|
||||||
|
qRegisterMetaType<QList<QPersistentModelIndex>>("QList<QPersistentModelIndex>");
|
||||||
|
qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>("QAbstractItemModel::LayoutChangeHint");
|
||||||
|
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|||||||
@ -162,7 +162,6 @@ void MainWindow::on_btn_test_clicked()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_btn_camera_clicked()
|
void MainWindow::on_btn_camera_clicked()
|
||||||
{
|
{
|
||||||
if(nullptr == ui_dialognetconfig){
|
if(nullptr == ui_dialognetconfig){
|
||||||
|
|||||||
@ -45,7 +45,7 @@ background-color: rgba(255, 255, 255, 0);</string>
|
|||||||
<widget class="QPushButton" name="btn_test">
|
<widget class="QPushButton" name="btn_test">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>840</x>
|
<x>960</x>
|
||||||
<y>21</y>
|
<y>21</y>
|
||||||
<width>220</width>
|
<width>220</width>
|
||||||
<height>80</height>
|
<height>80</height>
|
||||||
@ -68,7 +68,7 @@ border: none;</string>
|
|||||||
<widget class="QPushButton" name="btn_camera">
|
<widget class="QPushButton" name="btn_camera">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>555</x>
|
<x>440</x>
|
||||||
<y>21</y>
|
<y>21</y>
|
||||||
<width>220</width>
|
<width>220</width>
|
||||||
<height>80</height>
|
<height>80</height>
|
||||||
@ -165,7 +165,7 @@ background-color: rgba(255, 255, 255, 0);</string>
|
|||||||
<widget class="QPushButton" name="btn_start">
|
<widget class="QPushButton" name="btn_start">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>1220</x>
|
<x>1260</x>
|
||||||
<y>21</y>
|
<y>21</y>
|
||||||
<width>80</width>
|
<width>80</width>
|
||||||
<height>80</height>
|
<height>80</height>
|
||||||
@ -187,7 +187,7 @@ background-color: rgba(255, 255, 255, 0);</string>
|
|||||||
<widget class="QPushButton" name="btn_stop">
|
<widget class="QPushButton" name="btn_stop">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>1360</x>
|
<x>1400</x>
|
||||||
<y>21</y>
|
<y>21</y>
|
||||||
<width>80</width>
|
<width>80</width>
|
||||||
<height>80</height>
|
<height>80</height>
|
||||||
@ -206,6 +206,29 @@ background-color: rgba(255, 255, 255, 0);</string>
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QPushButton" name="btn_algo_config">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>700</x>
|
||||||
|
<y>21</y>
|
||||||
|
<width>220</width>
|
||||||
|
<height>80</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>18</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">image: url(:/resource/config_algo.png);
|
||||||
|
background-color: rgb(38, 40, 47);
|
||||||
|
border: none;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QFrame" name="detect_result">
|
<widget class="QFrame" name="detect_result">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
|
|||||||
@ -4,6 +4,9 @@
|
|||||||
#include <QTableWidgetItem>
|
#include <QTableWidgetItem>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
TearingDataTableWidget::TearingDataTableWidget(QWidget *parent)
|
TearingDataTableWidget::TearingDataTableWidget(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
@ -32,7 +35,8 @@ void TearingDataTableWidget::setupTable()
|
|||||||
{
|
{
|
||||||
// 设置表头标签
|
// 设置表头标签
|
||||||
QStringList headers;
|
QStringList headers;
|
||||||
headers << "ID" << "等级" << "状态" << "类型" /*<< "起始行" << "结束行" */<< "深度" << "宽度" << "长度" << "老化";
|
// headers << "ID" << "等级" << "状态" << "类型" /*<< "起始行" << "结束行" */<< "深度" << "宽度" << "长度" << "老化";
|
||||||
|
headers << "ID" << "状态" << "类型" << "深度(mm)" << "宽度(mm)" << "长度(mm)";
|
||||||
|
|
||||||
// 设置表格属性
|
// 设置表格属性
|
||||||
m_tableWidget->setColumnCount(headers.size());
|
m_tableWidget->setColumnCount(headers.size());
|
||||||
@ -50,14 +54,12 @@ void TearingDataTableWidget::setupTable()
|
|||||||
m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
||||||
|
|
||||||
// 设置列宽
|
// 设置列宽
|
||||||
m_tableWidget->setColumnWidth(0, 52); // ID列
|
m_tableWidget->setColumnWidth(0, 62); // ID列
|
||||||
m_tableWidget->setColumnWidth(1, 45); // 等级列
|
m_tableWidget->setColumnWidth(1, 100); // 状态列
|
||||||
m_tableWidget->setColumnWidth(2, 80); // 状态列
|
m_tableWidget->setColumnWidth(2, 80); // 类型列
|
||||||
m_tableWidget->setColumnWidth(3, 45); // 类型列
|
m_tableWidget->setColumnWidth(3, 100); // 深度列
|
||||||
m_tableWidget->setColumnWidth(4, 80); // 深度列
|
m_tableWidget->setColumnWidth(4, 100); // 宽度列
|
||||||
m_tableWidget->setColumnWidth(5, 80); // 宽度列
|
m_tableWidget->setColumnWidth(5, 100); // 长度列
|
||||||
m_tableWidget->setColumnWidth(6, 80); // 长度列
|
|
||||||
m_tableWidget->setColumnWidth(7, 80); // 老化列
|
|
||||||
#endif
|
#endif
|
||||||
// 设置样式表
|
// 设置样式表
|
||||||
m_tableWidget->setStyleSheet(
|
m_tableWidget->setStyleSheet(
|
||||||
@ -75,25 +77,46 @@ void TearingDataTableWidget::setupTable()
|
|||||||
" padding: 4px;"
|
" padding: 4px;"
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 启用表格排序功能
|
||||||
|
m_tableWidget->setSortingEnabled(true);
|
||||||
|
|
||||||
|
// 设置默认按ID列升序排序
|
||||||
|
m_tableWidget->sortItems(0, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearingDataTableWidget::addData(const TearingData &data)
|
void TearingDataTableWidget::addData(const TearingData &data)
|
||||||
{
|
{
|
||||||
// 将数据显示到QTableWidget上
|
// 查找是否已存在相同ID的行
|
||||||
int row = m_tableWidget->rowCount();
|
int existingRow = findExistingRowById(data.id);
|
||||||
m_tableWidget->insertRow(row);
|
|
||||||
|
|
||||||
// 使用结构体数据填充表格
|
int row;
|
||||||
m_tableWidget->setItem(row, 0, new QTableWidgetItem(data.id));
|
if (existingRow >= 0) {
|
||||||
m_tableWidget->setItem(row, 1, new QTableWidgetItem(data.level));
|
// 如果存在相同ID,更新该行
|
||||||
m_tableWidget->setItem(row, 2, new QTableWidgetItem(data.tearStatus));
|
row = existingRow;
|
||||||
m_tableWidget->setItem(row, 3, new QTableWidgetItem(data.tearType));
|
} else {
|
||||||
// m_tableWidget->setItem(row, 4, new QTableWidgetItem(data.statLineIdx));
|
// 如果不存在,插入新行
|
||||||
// m_tableWidget->setItem(row, 5, new QTableWidgetItem(data.endLineIdx));
|
row = m_tableWidget->rowCount();
|
||||||
m_tableWidget->setItem(row, 4, new QTableWidgetItem(data.tearDepth));
|
m_tableWidget->insertRow(row);
|
||||||
m_tableWidget->setItem(row, 5, new QTableWidgetItem(data.tearWidth));
|
}
|
||||||
m_tableWidget->setItem(row, 6, new QTableWidgetItem(data.tearLength));
|
|
||||||
m_tableWidget->setItem(row, 7, new QTableWidgetItem(data.older));
|
// 使用结构体数据填充表格,状态和类型显示中文,并设置居中对齐
|
||||||
|
NumericTableWidgetItem *idItem = new NumericTableWidgetItem(data.id);
|
||||||
|
idItem->setTextAlignment(Qt::AlignCenter); // ID列文字居中显示
|
||||||
|
m_tableWidget->setItem(row, 0, idItem);
|
||||||
|
|
||||||
|
QTableWidgetItem *statusItem = new QTableWidgetItem(getTearStatusText(data.tearStatus));
|
||||||
|
statusItem->setTextAlignment(Qt::AlignCenter); // 状态列文字居中显示
|
||||||
|
m_tableWidget->setItem(row, 1, statusItem);
|
||||||
|
|
||||||
|
QTableWidgetItem *typeItem = new QTableWidgetItem(getTearTypeText(data.tearType));
|
||||||
|
typeItem->setTextAlignment(Qt::AlignCenter); // 类型列文字居中显示
|
||||||
|
m_tableWidget->setItem(row, 2, typeItem);
|
||||||
|
|
||||||
|
m_tableWidget->setItem(row, 3, new QTableWidgetItem(data.tearDepth));
|
||||||
|
m_tableWidget->setItem(row, 4, new QTableWidgetItem(data.tearWidth));
|
||||||
|
// m_tableWidget->setItem(row, 5, new QTableWidgetItem(data.tearLength));
|
||||||
|
m_tableWidget->setItem(row, 5, new QTableWidgetItem(data.statLineIdx));
|
||||||
|
|
||||||
// 设置item的文本颜色
|
// 设置item的文本颜色
|
||||||
for (int i = 0; i < m_tableWidget->horizontalHeader()->count(); i++) {
|
for (int i = 0; i < m_tableWidget->horizontalHeader()->count(); i++) {
|
||||||
@ -102,6 +125,9 @@ void TearingDataTableWidget::addData(const TearingData &data)
|
|||||||
item->setForeground(QBrush(Qt::white));
|
item->setForeground(QBrush(Qt::white));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保持表格按ID列排序
|
||||||
|
m_tableWidget->sortItems(0, Qt::AscendingOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearingDataTableWidget::addData(const std::vector<TearingData> &dataList)
|
void TearingDataTableWidget::addData(const std::vector<TearingData> &dataList)
|
||||||
@ -122,3 +148,85 @@ void TearingDataTableWidget::clearData()
|
|||||||
{
|
{
|
||||||
m_tableWidget->setRowCount(0);
|
m_tableWidget->setRowCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TearingDataTableWidget::getTearStatusText(const QString &status)
|
||||||
|
{
|
||||||
|
// 将ESG_tearStatus枚举值转换为中文显示
|
||||||
|
if (status == "0" || status.contains("Uknown")) {
|
||||||
|
return "未知";
|
||||||
|
} else if (status == "1" || status.contains("New")) {
|
||||||
|
return "新发现";
|
||||||
|
} else if (status == "2" || status.contains("Growing")) {
|
||||||
|
return "正在增长";
|
||||||
|
} else if (status == "3" || status.contains("Ended")) {
|
||||||
|
return "撕裂结束";
|
||||||
|
} else if (status == "4" || status.contains("Invalid")) {
|
||||||
|
return "无效撕裂";
|
||||||
|
}
|
||||||
|
return status; // 如果无法识别,返回原值
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TearingDataTableWidget::getTearTypeText(const QString &type)
|
||||||
|
{
|
||||||
|
// 将ESG_tearType枚举值转换为中文显示
|
||||||
|
if (type == "0" || type.contains("Uknown")) {
|
||||||
|
return "未知";
|
||||||
|
} else if (type == "1" || type.contains("MachineDir")) {
|
||||||
|
return "纵撕";
|
||||||
|
} else if (type == "2" || type.contains("CrossWise")) {
|
||||||
|
return "横撕";
|
||||||
|
}
|
||||||
|
return type; // 如果无法识别,返回原值
|
||||||
|
}
|
||||||
|
|
||||||
|
int TearingDataTableWidget::findExistingRowById(const QString &id)
|
||||||
|
{
|
||||||
|
// 在表格中查找具有相同ID的行
|
||||||
|
for (int row = 0; row < m_tableWidget->rowCount(); ++row) {
|
||||||
|
QTableWidgetItem *item = m_tableWidget->item(row, 0); // ID在第0列
|
||||||
|
if (item && item->text() == id) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // 未找到
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumericTableWidgetItem类的实现
|
||||||
|
NumericTableWidgetItem::NumericTableWidgetItem(const QString &text)
|
||||||
|
: QTableWidgetItem(text)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NumericTableWidgetItem::operator<(const QTableWidgetItem &other) const
|
||||||
|
{
|
||||||
|
// 尝试将文本转换为数字进行比较
|
||||||
|
double thisValue = toDouble();
|
||||||
|
double otherValue = static_cast<const NumericTableWidgetItem*>(&other)->toDouble();
|
||||||
|
|
||||||
|
// 如果两个值都有效,则按数字比较
|
||||||
|
if (thisValue != -1 && otherValue != -1) {
|
||||||
|
return thisValue < otherValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则按默认的字符串比较
|
||||||
|
return QTableWidgetItem::operator<(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
double NumericTableWidgetItem::toDouble() const
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
// 尝试直接转换为double
|
||||||
|
double value = text().toDouble(&ok);
|
||||||
|
if (ok) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果直接转换失败,尝试提取数字部分
|
||||||
|
QRegExp rx("(\\d+)");
|
||||||
|
if (rx.indexIn(text()) != -1) {
|
||||||
|
return rx.cap(1).toDouble(&ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果所有方法都失败,返回-1表示无效值
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|||||||
@ -3,12 +3,25 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
|
#include <QTableWidgetItem>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "IStatusUpdate.h"
|
#include "IStatusUpdate.h"
|
||||||
|
|
||||||
|
// 自定义TableWidgetItem类,支持按数字值排序
|
||||||
|
class NumericTableWidgetItem : public QTableWidgetItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NumericTableWidgetItem(const QString &text);
|
||||||
|
|
||||||
|
bool operator<(const QTableWidgetItem &other) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
double toDouble() const;
|
||||||
|
};
|
||||||
|
|
||||||
class TearingDataTableWidget : public QWidget
|
class TearingDataTableWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -25,6 +38,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
void setupTable();
|
void setupTable();
|
||||||
|
QString getTearStatusText(const QString &status);
|
||||||
|
QString getTearTypeText(const QString &type);
|
||||||
|
int findExistingRowById(const QString &id);
|
||||||
|
|
||||||
|
// 排序相关的私有方法
|
||||||
|
void connectHeaderSignals();
|
||||||
|
|
||||||
QTableWidget *m_tableWidget;
|
QTableWidget *m_tableWidget;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -199,22 +199,22 @@ void BeltTearingPresenter::sendTestData(std::string fileName){
|
|||||||
std::vector<SVzNL3DPosition> sVzNLPostion;
|
std::vector<SVzNL3DPosition> sVzNLPostion;
|
||||||
sVzNLPostion.clear();
|
sVzNLPostion.clear();
|
||||||
|
|
||||||
bool bFindLineNum = true;
|
int nIndex = 0;
|
||||||
int nLaserPointIdx = 0;
|
|
||||||
|
|
||||||
SVzLaserLineData pLaserLine;
|
SVzLaserLineData pLaserLine;
|
||||||
|
|
||||||
while (std::getline(inputFile, line)) {
|
while (std::getline(inputFile, line)) {
|
||||||
if (line.find("Line_") == 0) {
|
if (line.find("Line_") == 0) {
|
||||||
|
|
||||||
if(!sVzNLPostion.empty()){
|
if(!sVzNLPostion.empty()){
|
||||||
pLaserLine.llFrameIdx = nLaserPointIdx;
|
|
||||||
pLaserLine.p3DPoint = sVzNLPostion.data();
|
pLaserLine.p3DPoint = sVzNLPostion.data();
|
||||||
pLaserLine.nPointCount = sVzNLPostion.size();
|
pLaserLine.nPointCount = sVzNLPostion.size();
|
||||||
processPointCloudData(&pLaserLine);
|
processPointCloudData(&pLaserLine);
|
||||||
}
|
}
|
||||||
|
sscanf(line.c_str(), "Line_%lld_%lld", &pLaserLine.llFrameIdx, &pLaserLine.llTimeStamp);
|
||||||
sVzNLPostion.clear();
|
sVzNLPostion.clear();
|
||||||
|
|
||||||
|
nIndex++;
|
||||||
|
|
||||||
} else if (line.find("{") == 0) {
|
} else if (line.find("{") == 0) {
|
||||||
float lx, ly, rx, ry;
|
float lx, ly, rx, ry;
|
||||||
SVzNL3DPosition pos;
|
SVzNL3DPosition pos;
|
||||||
@ -226,6 +226,10 @@ void BeltTearingPresenter::sendTestData(std::string fileName){
|
|||||||
sVzNLPostion.push_back(pos);
|
sVzNLPostion.push_back(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(nIndex > 500){
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
// std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
// std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,31 +402,34 @@ void BeltTearingPresenter::processPointCloudData(const SVzLaserLineData* pLaserL
|
|||||||
// 将激光线数据添加到队列(用于图像生成)
|
// 将激光线数据添加到队列(用于图像生成)
|
||||||
addLaserLineToQueue(pLaserLine);
|
addLaserLineToQueue(pLaserLine);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 调用SDK算法
|
// 调用SDK算法
|
||||||
int errorCode = 0;
|
int errorCode = 0;
|
||||||
|
|
||||||
std::vector<SSG_beltTearingInfo> beltTearings_new;
|
|
||||||
std::vector<SSG_beltTearingInfo> beltTearings_growing;
|
|
||||||
std::vector<SSG_beltTearingInfo> beltTearings_ended;
|
|
||||||
std::vector<SSG_beltTearingInfo> beltTearings_unknown;
|
|
||||||
|
|
||||||
if(!m_bInitAlgo){
|
if(!m_bInitAlgo){
|
||||||
m_hLineWorkers.resize(pLaserLine->nPointCount);
|
m_hLineWorkers.resize(pLaserLine->nPointCount);
|
||||||
|
|
||||||
|
m_beltTearings_new.clear();
|
||||||
|
m_beltTearings_new.shrink_to_fit();
|
||||||
|
m_beltTearings_growing.clear();
|
||||||
|
m_beltTearings_growing.shrink_to_fit();
|
||||||
|
m_beltTearings_ended.clear();
|
||||||
|
m_beltTearings_ended.shrink_to_fit();
|
||||||
|
m_beltTearings_unknown.clear();
|
||||||
|
m_beltTearings_unknown.shrink_to_fit();
|
||||||
|
|
||||||
sg_detectBeltTearing(
|
sg_detectBeltTearing(
|
||||||
NULL, //空扫描线,用于复位内部静态变量
|
NULL, //空扫描线,用于复位内部静态变量
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&errorCode,
|
&errorCode,
|
||||||
m_hLineWorkers,
|
m_hLineWorkers,
|
||||||
beltTearings_new,
|
m_beltTearings_new,
|
||||||
beltTearings_growing,
|
m_beltTearings_growing,
|
||||||
beltTearings_ended,
|
m_beltTearings_ended,
|
||||||
beltTearings_unknown, //未判明,应用无需处理。
|
m_beltTearings_unknown, //未判明,应用无需处理。
|
||||||
m_algorithmParam);
|
m_algorithmParam);
|
||||||
m_bInitAlgo = true;
|
m_bInitAlgo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用SDK算法进行撕裂检测
|
// 使用SDK算法进行撕裂检测
|
||||||
@ -437,27 +444,36 @@ void BeltTearingPresenter::processPointCloudData(const SVzLaserLineData* pLaserL
|
|||||||
algorithmData.nPositionCnt,
|
algorithmData.nPositionCnt,
|
||||||
&errorCode,
|
&errorCode,
|
||||||
m_hLineWorkers,
|
m_hLineWorkers,
|
||||||
beltTearings_new,
|
m_beltTearings_new,
|
||||||
beltTearings_growing,
|
m_beltTearings_growing,
|
||||||
beltTearings_ended,
|
m_beltTearings_ended,
|
||||||
beltTearings_unknown,
|
m_beltTearings_unknown,
|
||||||
m_algorithmParam
|
m_algorithmParam
|
||||||
);
|
);
|
||||||
|
|
||||||
// 合并所有检测结果
|
// 合并所有检测结果
|
||||||
std::vector<SSG_beltTearingInfo> allResults;
|
std::vector<SSG_beltTearingInfo> allResults;
|
||||||
allResults.reserve(beltTearings_new.size() + beltTearings_growing.size() +
|
allResults.reserve(m_beltTearings_new.size() + m_beltTearings_growing.size() + m_beltTearings_ended.size());
|
||||||
beltTearings_ended.size() + beltTearings_unknown.size());
|
|
||||||
|
|
||||||
allResults.insert(allResults.end(), beltTearings_new.begin(), beltTearings_new.end());
|
allResults.insert(allResults.end(), m_beltTearings_new.begin(), m_beltTearings_new.end());
|
||||||
// allResults.insert(allResults.end(), beltTearings_growing.begin(), beltTearings_growing.end());
|
allResults.insert(allResults.end(), m_beltTearings_growing.begin(), m_beltTearings_growing.end());
|
||||||
allResults.insert(allResults.end(), beltTearings_ended.begin(), beltTearings_ended.end());
|
allResults.insert(allResults.end(), m_beltTearings_ended.begin(), m_beltTearings_ended.end());
|
||||||
// allResults.insert(allResults.end(), beltTearings_unknown.begin(), beltTearings_unknown.end());
|
// allResults.insert(allResults.end(), m_beltTearings_unknown.begin(), m_beltTearings_unknown.end());
|
||||||
|
|
||||||
LOG_DEBUG("line count : %d algo detect count: %d (new:%d, growing:%d, ended:%d, unknown:%d)[%d]\n",
|
LOG_DEBUG("line count : %d algo detect count: %d (new:%d, growing:%d, ended:%d, unknown:%d)[%d]\n",
|
||||||
algorithmData.nPositionCnt,
|
algorithmData.nPositionCnt,
|
||||||
allResults.size(), beltTearings_new.size(), beltTearings_growing.size(),
|
allResults.size(), m_beltTearings_new.size(), m_beltTearings_growing.size(),
|
||||||
beltTearings_ended.size(), beltTearings_unknown.size(), errorCode);
|
m_beltTearings_ended.size(), m_beltTearings_unknown.size(), errorCode);
|
||||||
|
|
||||||
|
for(auto& item : m_beltTearings_new){
|
||||||
|
LOG_DEBUG("-----new %lld ID: %d st: %d depth: %f \n", pLaserLine->llFrameIdx, item.tearID, item.tearStatus, item.tearDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for(auto& item : m_beltTearings_ended){
|
||||||
|
LOG_DEBUG("-----end %lld ID: %d st: %d depth: %f \n", pLaserLine->llFrameIdx, item.tearID, item.tearStatus, item.tearDepth);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// 发送检测结果
|
// 发送检测结果
|
||||||
if (!allResults.empty()) {
|
if (!allResults.empty()) {
|
||||||
|
|||||||
@ -86,14 +86,19 @@ private:
|
|||||||
// SDK算法相关
|
// SDK算法相关
|
||||||
std::atomic<bool> m_bInitAlgo{false};
|
std::atomic<bool> m_bInitAlgo{false};
|
||||||
std::vector<SSG_hLineProInfo> m_hLineWorkers;
|
std::vector<SSG_hLineProInfo> m_hLineWorkers;
|
||||||
|
|
||||||
SSG_beltTearingParam m_algorithmParam;
|
SSG_beltTearingParam m_algorithmParam;
|
||||||
|
std::vector<SSG_beltTearingInfo> m_beltTearings_new;
|
||||||
|
std::vector<SSG_beltTearingInfo> m_beltTearings_growing;
|
||||||
|
std::vector<SSG_beltTearingInfo> m_beltTearings_ended;
|
||||||
|
std::vector<SSG_beltTearingInfo> m_beltTearings_unknown;
|
||||||
|
|
||||||
// 激光线队列管理
|
// 激光线队列管理
|
||||||
std::deque<SVzLaserLineData> m_laserLineQueue; // 激光线数据队列
|
std::deque<SVzLaserLineData> m_laserLineQueue; // 激光线数据队列
|
||||||
std::mutex m_queueMutex; // 队列访问互斥锁
|
std::mutex m_queueMutex; // 队列访问互斥锁
|
||||||
unsigned long long m_lineCounter; // 新增线条计数器
|
unsigned long long m_lineCounter; // 新增线条计数器
|
||||||
static const int MAX_QUEUE_SIZE = 200; // 最大队列大小
|
static const int MAX_QUEUE_SIZE = 200; // 最大队列大小
|
||||||
static const int IMAGE_GENERATION_INTERVAL = 10; // 每10条线生成一次图像
|
static const int IMAGE_GENERATION_INTERVAL = 20; // 每20条线生成一次图像
|
||||||
|
|
||||||
// 相机状态回调函数
|
// 相机状态回调函数
|
||||||
static void OnStatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
static void OnStatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user