Files
EJM_Display/Pages/P401_CuttingPage.cpp

290 lines
14 KiB
C++
Raw Permalink Normal View History

2025-08-20 23:06:28 +08:00
#include "P401_CuttingPage.h"
#include "ui_P401_CuttingPage.h"
2025-09-30 17:42:22 +08:00
#include <GlobalDefinitions/Variable.h>
#include <FileOperation/ConfigFiles.h>
2025-08-20 23:06:28 +08:00
P401_CuttingPage::P401_CuttingPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::P401_CuttingPage)
{
ui->setupUi(this);
2025-09-30 17:42:22 +08:00
2025-10-21 11:11:52 +08:00
// QTimer::singleShot(1000, this, &P401_CuttingPage::WinInit);
2025-09-30 17:42:22 +08:00
// QTimer::singleShot(2000, this, &P401_CuttingPage::Show3D);
2025-10-21 11:11:52 +08:00
2025-09-30 17:42:22 +08:00
2025-08-20 23:06:28 +08:00
}
P401_CuttingPage::~P401_CuttingPage()
{
delete ui;
}
2025-09-30 17:42:22 +08:00
void P401_CuttingPage::WinInit(){
2025-10-14 20:05:38 +08:00
for (int row = 1; row < CutConditionConfigFile.size()-1; ++row)
2025-09-30 17:42:22 +08:00
{
2025-10-21 11:11:52 +08:00
QString TextObjName = QString("Cut_SSConditions_%1").arg(row);
2025-09-30 17:42:22 +08:00
QLabel* Label = findChild<QLabel*>(TextObjName);
if (Label) {
2025-10-10 17:44:10 +08:00
QString Text = CutConditionConfigFile.at(row)[1];
2025-09-30 17:42:22 +08:00
Text.replace("\\n","\n",Qt::CaseInsensitive);
Label->setText(Text);
}
2025-10-10 17:44:10 +08:00
TrueColor.append(CutConditionConfigFile.at(row)[2]);
FalseColor.append(CutConditionConfigFile.at(row)[3]);
2025-09-30 17:42:22 +08:00
}
2025-10-21 11:11:52 +08:00
// 现在 ui->Cut_CPW_1 已经是一个 CurvePlotWidget*
ui->Cut_CPW_1->addSeries("电机电流U", Qt::green);
ui->Cut_CPW_1->addSeries("电机电流V", Qt::blue);
ui->Cut_CPW_1->addSeries("电机电流W", Qt::darkCyan);
// 现在 ui->Cut_CPW_1 已经是一个 CurvePlotWidget*
ui->Cut_CPW_2->addSeries("电机温度", Qt::green);
2025-09-30 17:42:22 +08:00
//所用定时器初始化
QTimer* UIRefresh_Timer = new QTimer(this);
connect(UIRefresh_Timer, &QTimer::timeout, this, &P401_CuttingPage::UIRefreshTimeOut);
UIRefresh_Timer->setInterval(100); // 设置定时器间隔为 1000 毫秒1 秒)
UIRefresh_Timer->start();
//所用定时器初始化
QTimer* TrailRefresh_Timer = new QTimer(this);
connect(TrailRefresh_Timer, &QTimer::timeout, this, &P401_CuttingPage::TrailRefreshTimeOut);
2025-10-21 11:11:52 +08:00
TrailRefresh_Timer->setInterval(10000); // 设置定时器间隔为 1000 毫秒1 秒)
2025-09-30 17:42:22 +08:00
TrailRefresh_Timer->start();
}
void P401_CuttingPage::Show3D()
{
2025-10-10 17:44:10 +08:00
DevName3D = "截割电机";
2025-09-30 17:42:22 +08:00
mObjLoader = new ObjLoader();
mObjLoader->setEnDebug(true);
mObjLoader->init3DScene(ui->Frame_Dev3D);
mObjLoader->setCameraSpeed(200.0, 200.0);
// 准备模型路径
2025-10-14 20:05:38 +08:00
QString filePath = ConfigurationPath + "3D模型文件/掘锚一体机/电机/" + DevName3D + ".obj";
2025-09-30 17:42:22 +08:00
m_currentDevName = DevName3D;
m_currentFilePath = filePath;
2025-10-10 17:44:10 +08:00
m_currentPosition = QVector3D(1052.00, 0.00273132, 0);
2025-09-30 17:42:22 +08:00
// 检查文件是否存在
if (!QFile::exists(filePath)) {
qCritical() << "模型文件不存在: " << filePath;
return;
}
// 创建工作线程和工作对象
m_workerThread = new QThread(this);
m_workerLoader = new ObjLoader(); // 专用预处理加载器
// 移动工作对象到工作线程
m_workerLoader->moveToThread(m_workerThread);
// 连接信号槽
connect(m_workerThread, &QThread::started, [=]() {
// 在工作线程中预处理模型(仅计算中心和半径)
QVector3D center = m_workerLoader->parseObjCenter(filePath);
float radius = m_workerLoader->calculateModelRadiusFromFile(filePath);
emit preprocessFinished(center, radius);
});
// 预处理完成后,在主线程加载模型
connect(this, &P401_CuttingPage::preprocessFinished, this, [=](QVector3D center, float radius) {
m_modelCenter = center;
m_modelRadius = radius;
// 使用定时器确保在主线程事件循环中执行
QTimer::singleShot(0, this, [=]() {
emit loadModelRequest(m_currentDevName, m_currentFilePath, center, radius);
});
// 清理工作线程
m_workerThread->quit();
m_workerThread->wait();
m_workerLoader->deleteLater();
});
// 主线程中实际加载模型
connect(this, &P401_CuttingPage::loadModelRequest, this, [=](const QString& devName, const QString& filePath, QVector3D center, float radius) {
bool LoaderOK = mObjLoader->loadModelAsync(devName, filePath, QVector3D(0, 0, 0), center, radius);
if (!LoaderOK) {
2025-10-10 17:44:10 +08:00
qCritical() << "截割电机加载:失败";
2025-09-30 17:42:22 +08:00
return;
}
mObjLoader->addAxisGizmo(nullptr, 5.0f);
mObjLoader->addAxisGizmo(mObjLoader->getDevice(devName)->entity, 3.0f);
2025-10-10 17:44:10 +08:00
SetPos(0.005,QVector3D(1052.00, 0.00273132, 0),QVector3D(0, 0, 0));
2025-09-30 17:42:22 +08:00
if (LoaderOK) {
QTimer *RotateDev_Timer = new QTimer(this);
connect(RotateDev_Timer, &QTimer::timeout, this, &P401_CuttingPage::RotateDev);
RotateDev_Timer->setInterval(33);
RotateDev_Timer->start();
}
});
// 启动工作线程
m_workerThread->start();
}
void P401_CuttingPage::SetPos(float Zoom,QVector3D Move,QVector3D Pos){
mObjLoader->scaleDevice(DevName3D,Zoom);
mObjLoader->moveArmLocalOriginTo(DevName3D, Move);//14.1, -1.4, 3.4
mObjLoader->setParentDevicePosition(DevName3D, Pos); // 世界坐标
// 6. 重置相机(确保能看到所有设备)
Qt3DRender::QCamera* cam = mObjLoader->getCamera();
if (cam) {
cam->setPosition(QVector3D(0, 3, 12)); // 相机在 Z 轴 30 位置,远离模型
cam->setViewCenter(QVector3D(0, 0, 0)); // 看向电控箱体的世界位置
}
}
2025-10-10 17:44:10 +08:00
void P401_CuttingPage::SetProgressBar(QProgressBar *PB,const uint16_t Value,const uint8_t ColorIndex,const QStringList Color){
2025-09-30 17:42:22 +08:00
PB->setValue(Value);
if(ColorIndex < Color.length()){
PB->setStyleSheet("QProgressBar {\n background-color: transparent;\n border: 2px solid #888888;\n border-radius: 3px;\n}\nQProgressBar::chunk {\n background-color:"+Color[ColorIndex]+";\n}");
}
}
2025-10-10 17:44:10 +08:00
void P401_CuttingPage::SetProgressBar(QProgressBar *PB,QLCDNumber *LCD,const QString NodeGroup,const QString NodeLCD,const QStringList Color){
// 从OPC节点获取油位显示组数据32位无符号整数
2025-10-16 17:40:00 +08:00
uint32_t PB_Group = getNodeValue("" + NodeGroup).toUInt();
2025-09-30 17:42:22 +08:00
2025-10-10 17:44:10 +08:00
// 从32位数据中拆分出16位油位百分比值和颜色值
uint16_t Percentage = static_cast<uint16_t>(PB_Group >> 16); // 高16位百分比
uint16_t ColorIndex = static_cast<uint16_t>(PB_Group & 0xFFFF); // 低16位颜色值索引
2025-09-30 17:42:22 +08:00
2025-10-10 17:44:10 +08:00
// 设置油位进度条显示(百分比、颜色和样式)
SetProgressBar(PB, Percentage, ColorIndex, Color);
2025-09-30 17:42:22 +08:00
2025-10-10 17:44:10 +08:00
// 在LCD上显示实际油位测量值
2025-10-16 17:40:00 +08:00
LCD->display(getNodeValue("" +NodeLCD).toReal());
2025-10-10 17:44:10 +08:00
}
void P401_CuttingPage::UIRefreshTimeOut()
{
2025-10-21 11:11:52 +08:00
if(!gPageIndexStr.contains("P04"))
2025-10-10 17:44:10 +08:00
return;
2025-10-21 11:11:52 +08:00
// 使用多核心管理器异步获取切割页面数据
//MultiCoreManager::instance()->submitTask([this]() {
// 准备数据容器
QMap<QString, QVariant> cuttingData;
// 异步读取切割页面数据
cuttingData["PB_Group1"] = getNodeValue("PB_Curr_Cut.PageGroup1");
cuttingData["PB_Group2"] = getNodeValue("PB_Curr_Cut.PageGroup2");
cuttingData["PB_MotorTemp"] = getNodeValue("PB_Temp_Cut.PageGroup");
cuttingData["SSConditions"] = getNodeValue("StartStopConditions.Cut");
cuttingData["IN_PhaseCut_Filtered30_U"] = getNodeValue("IN_PhaseCut.Filtered30_U");
cuttingData["IN_PhaseCut_Filtered30_V"] = getNodeValue("IN_PhaseCut.Filtered30_V");
cuttingData["IN_PhaseCut_Filtered30_W"] = getNodeValue("IN_PhaseCut.Filtered30_W");
cuttingData["IN_PhaseCut_Filtered_Temp"] = getNodeValue("IN_PhaseCut.Filtered_Temp");
cuttingData["PB_Pressure_Cut"] = getNodeValue("PB_Pressure_Cut.PageGroup");
cuttingData["IN_Sersor_Pressure_Cut"] = getNodeValue("IN_Sersor.Pressure_Cut");
cuttingData["PB_Pressure_Cutt"] = getNodeValue("PB_Pressure_Cutt.PageGroup");
cuttingData["IN_Sersor_Pressure_Cutt"] = getNodeValue("IN_Sersor.Pressure_Cutt");
cuttingData["PB_Pressure_CutSpray"] = getNodeValue("PB_Pressure_CutSpray.PageGroup");
cuttingData["IN_Sersor_Pressure_CutSpray"] = getNodeValue("IN_Sersor.Pressure_CutSpray");
cuttingData["PB_SprayFlow_Cut"] = getNodeValue("PB_SprayFlow_Cut.PageGroup");
cuttingData["IN_Sersor_SprayFlow_Cut"] = getNodeValue("IN_Sersor.SprayFlow_Cut");
// 在主线程中更新UI
QMetaObject::invokeMethod(this, [this, cuttingData]() {
/************************************* 电机基本信息 *************************************/
// 从32位数据中提取16位百分比值
uint32_t PB_Group1 = cuttingData["PB_Group1"].toUInt();
uint32_t PB_Group2 = cuttingData["PB_Group2"].toUInt();
uint32_t PB_MotorTemp = cuttingData["PB_MotorTemp"].toUInt();
uint32_t SSConditions = cuttingData["SSConditions"].toUInt();
uint16_t PercentageCurU = static_cast<uint16_t>(PB_Group1 >> 16);
uint16_t PercentageCurV = static_cast<uint16_t>(PB_Group1 & 0xFFFF);
uint16_t PercentageCurW = static_cast<uint16_t>(PB_Group2 >> 16);
uint16_t PercentageTmpColor = static_cast<uint16_t>(PB_Group2 & 0xFFFF);
uint16_t PercentageMotorTemp = static_cast<uint16_t>(PB_MotorTemp >> 16);
uint16_t ColorTemp = static_cast<uint16_t>(PB_MotorTemp & 0xFFFF);
uint8_t ColorU = (PercentageTmpColor / 10) % 10;
uint8_t ColorV = (PercentageTmpColor / 100) % 10;
uint8_t ColorW = PercentageTmpColor % 10;
// 设置进度条显示
SetProgressBar(ui->PB_Cur_1, PercentageCurU, ColorU, glMotorCurColor);
SetProgressBar(ui->PB_Cur_2, PercentageCurV, ColorV, glMotorCurColor);
SetProgressBar(ui->PB_Cur_3, PercentageCurW, ColorW, glMotorCurColor);
SetProgressBar(ui->PB_Temp, PercentageMotorTemp, ColorTemp, glMotorTempColor);
// 在LCD上显示实际测量值
ui->LCD_Cur_1->display(cuttingData["IN_PhaseCut_Filtered30_U"].toReal());
ui->LCD_Cur_2->display(cuttingData["IN_PhaseCut_Filtered30_V"].toReal());
ui->LCD_Cur_3->display(cuttingData["IN_PhaseCut_Filtered30_W"].toReal());
ui->LCD_Temp->display(cuttingData["IN_PhaseCut_Filtered_Temp"].toReal());
// 更新32个启停条件状态标签的显示样式
for (int i = 0; i < 32; ++i)
{
QLabel* Label = findChild<QLabel*>(QString("Cut_SSConditions_%1").arg(i+1));
if (Label) {
QString StyleStr = "border-image: url(:/Frames/null.png);\n";
StyleStr += getBitOf32Data(SSConditions, i, false) ? TrueColor[i] + "\n" : FalseColor[i] + "\n";
Label->setStyleSheet(StyleStr);
}
}
/**************************************************************************************/
/************************************ 截割油缸压力信息 ***********************************/
uint32_t pressureCutGroup = cuttingData["PB_Pressure_Cut"].toUInt();
uint16_t pressureCutPercentage = static_cast<uint16_t>(pressureCutGroup >> 16);
uint16_t pressureCutColorIndex = static_cast<uint16_t>(pressureCutGroup & 0xFFFF);
SetProgressBar(ui->PB_1, pressureCutPercentage, pressureCutColorIndex, glMotorCurColor);
ui->LCD_1->display(cuttingData["IN_Sersor_Pressure_Cut"].toReal());
/**************************************************************************************/
/************************************ 掏槽油缸压力信息 ***********************************/
uint32_t pressureCuttGroup = cuttingData["PB_Pressure_Cutt"].toUInt();
uint16_t pressureCuttPercentage = static_cast<uint16_t>(pressureCuttGroup >> 16);
uint16_t pressureCuttColorIndex = static_cast<uint16_t>(pressureCuttGroup & 0xFFFF);
SetProgressBar(ui->PB_2, pressureCuttPercentage, pressureCuttColorIndex, glMotorCurColor);
ui->LCD_2->display(cuttingData["IN_Sersor_Pressure_Cutt"].toReal());
/**************************************************************************************/
/************************************ 截割喷雾压力信息 ***********************************/
uint32_t pressureCutSprayGroup = cuttingData["PB_Pressure_CutSpray"].toUInt();
uint16_t pressureCutSprayPercentage = static_cast<uint16_t>(pressureCutSprayGroup >> 16);
uint16_t pressureCutSprayColorIndex = static_cast<uint16_t>(pressureCutSprayGroup & 0xFFFF);
SetProgressBar(ui->PB_3, pressureCutSprayPercentage, pressureCutSprayColorIndex, glMotorCurColor);
ui->LCD_3->display(cuttingData["IN_Sersor_Pressure_CutSpray"].toReal());
/**************************************************************************************/
/************************************ 截割喷雾流量信息 ***********************************/
uint32_t sprayFlowCutGroup = cuttingData["PB_SprayFlow_Cut"].toUInt();
uint16_t sprayFlowCutPercentage = static_cast<uint16_t>(sprayFlowCutGroup >> 16);
uint16_t sprayFlowCutColorIndex = static_cast<uint16_t>(sprayFlowCutGroup & 0xFFFF);
SetProgressBar(ui->PB_4, sprayFlowCutPercentage, sprayFlowCutColorIndex, glMotorCurColor);
ui->LCD_4->display(cuttingData["IN_Sersor_SprayFlow_Cut"].toReal());
/**************************************************************************************/
}, Qt::QueuedConnection);
// }, "cutting_page_ui_refresh");
2025-09-30 17:42:22 +08:00
}
void P401_CuttingPage::TrailRefreshTimeOut(){
2025-10-21 11:11:52 +08:00
ui->Cut_CPW_1->appendPoint(0, getNodeValue("IN_PhaseCut.Filtered30_U") .toReal());
ui->Cut_CPW_1->appendPoint(1, getNodeValue("IN_PhaseCut.Filtered30_V") .toReal());
ui->Cut_CPW_1->appendPoint(2, getNodeValue("IN_PhaseCut.Filtered30_W") .toReal());
ui->Cut_CPW_2->appendPoint(0,getNodeValue("IN_PhaseCut.Filtered_Temp") .toDouble());
2025-09-30 17:42:22 +08:00
}
void P401_CuttingPage::RotateDev(){
2025-10-10 17:44:10 +08:00
if(!gPageIndexStr.contains("P401"))
return;
2025-09-30 17:42:22 +08:00
mAngle = mAngle + 1;
if(mAngle > 360) mAngle =0;
mObjLoader->rotateArmToAbsoluteYAngle(DevName3D, mAngle);
}