Files
EJM_Display/Pages/P501_LoaderPage.cpp
2025-10-10 17:44:10 +08:00

290 lines
15 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "P501_LoaderPage.h"
#include "ui_P501_LoaderPage.h"
#include <GlobalDefinitions/Variable.h>
#include <FileOperation/ConfigFiles.h>
P501_LoaderPage::P501_LoaderPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::P501_LoaderPage)
{
ui->setupUi(this);
QTimer::singleShot(1000, this, &P501_LoaderPage::WinInit);
// QTimer::singleShot(2000, this, &P501_LoaderPage::Show3D);
}
P501_LoaderPage::~P501_LoaderPage()
{
delete ui;
}
void P501_LoaderPage::WinInit(){
for (int row = 1; row < CutConditionConfigFile.size(); ++row)
{
QString TextObjName = QString("Text_SSConditions_%1").arg(row);
QLabel* Label = findChild<QLabel*>(TextObjName);
if (Label) {
QString Text = CutConditionConfigFile.at(row)[1];
Text.replace("\\n","\n",Qt::CaseInsensitive);
Label->setText(Text);
}
TrueColor.append(CutConditionConfigFile.at(row)[2]);
FalseColor.append(CutConditionConfigFile.at(row)[3]);
}
// 现在 ui->CPW_1 已经是一个 CurvePlotWidget*
ui->CPW_L1->addSeries("左U", Qt::green);
ui->CPW_L1->addSeries("左V", Qt::blue);
ui->CPW_L1->addSeries("左W", Qt::darkCyan);
// 现在 ui->CPW_1 已经是一个 CurvePlotWidget*
ui->CPW_L2->addSeries("左温", Qt::green);
// 现在 ui->CPW_1 已经是一个 CurvePlotWidget*
ui->CPW_R1->addSeries("右U", Qt::green);
ui->CPW_R1->addSeries("右V", Qt::blue);
ui->CPW_R1->addSeries("右W", Qt::darkCyan);
// 现在 ui->CPW_1 已经是一个 CurvePlotWidget*
ui->CPW_R2->addSeries("右温", Qt::green);
//所用定时器初始化
QTimer* UIRefresh_Timer = new QTimer(this);
connect(UIRefresh_Timer, &QTimer::timeout, this, &P501_LoaderPage::UIRefreshTimeOut);
UIRefresh_Timer->setInterval(100); // 设置定时器间隔为 1000 毫秒1 秒)
UIRefresh_Timer->start();
//所用定时器初始化
QTimer* TrailRefresh_Timer = new QTimer(this);
connect(TrailRefresh_Timer, &QTimer::timeout, this, &P501_LoaderPage::TrailRefreshTimeOut);
TrailRefresh_Timer->setInterval(100); // 设置定时器间隔为 1000 毫秒1 秒)
TrailRefresh_Timer->start();
}
void P501_LoaderPage::Show3D()
{
DevName3D = "运输、铲板电机";
mObjLoader = new ObjLoader();
mObjLoader->setEnDebug(true);
mObjLoader->init3DScene(ui->Frame_Dev3D);
mObjLoader->setCameraSpeed(200.0, 200.0);
// 准备模型路径
QString filePath = "./3D模型文件/掘锚一体机/电机/" + DevName3D + ".obj";
m_currentDevName = DevName3D;
m_currentFilePath = filePath;
m_currentPosition = QVector3D(356.67, 65.0579, -0.231415);
// 检查文件是否存在
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, &P501_LoaderPage::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, &P501_LoaderPage::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) {
qCritical() << "装载电机加载:失败";
return;
}
mObjLoader->addAxisGizmo(nullptr, 5.0f);
mObjLoader->addAxisGizmo(mObjLoader->getDevice(devName)->entity, 3.0f);
SetPos(0.005,QVector3D(356.67, 65.0579, -0.231415),QVector3D(0, 0, 0));
if (LoaderOK) {
QTimer *RotateDev_Timer = new QTimer(this);
connect(RotateDev_Timer, &QTimer::timeout, this, &P501_LoaderPage::RotateDev);
RotateDev_Timer->setInterval(33);
RotateDev_Timer->start();
}
});
// 启动工作线程
m_workerThread->start();
}
void P501_LoaderPage::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)); // 看向电控箱体的世界位置
}
}
void P501_LoaderPage::SetProgressBar(QProgressBar *PB,const uint16_t Value,const uint8_t ColorIndex,const QStringList Color){
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}");
}
}
void P501_LoaderPage::SetProgressBar(QProgressBar *PB,QLCDNumber *LCD,const QString NodeGroup,const QString NodeLCD,const QStringList Color){
// 从OPC节点获取油位显示组数据32位无符号整数
uint32_t PB_Group = gOPC_NodeValue["ns=6;s=::AsGlobalPV:" + NodeGroup].toUInt();
// 从32位数据中拆分出16位油位百分比值和颜色值
uint16_t Percentage = static_cast<uint16_t>(PB_Group >> 16); // 高16位百分比
uint16_t ColorIndex = static_cast<uint16_t>(PB_Group & 0xFFFF); // 低16位颜色值索引
// 设置油位进度条显示(百分比、颜色和样式)
SetProgressBar(PB, Percentage, ColorIndex, Color);
// 在LCD上显示实际油位测量值
LCD->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:" +NodeLCD].toReal());
}
void P501_LoaderPage::UIRefreshTimeOut()
{
if(!gPageIndexStr.contains("P501"))
return;
/************************************* 电机基本信息 *************************************/
// 从OPC节点获取切割设备电机相关的状态数据32位无符号整数
uint32_t PB_GroupL1 = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Curr_LoaderL.PageGroup1"].toUInt(); // 电流显示组1数据
uint32_t PB_GroupL2 = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Curr_LoaderL.PageGroup2"].toUInt(); // 电流显示组2数据
uint32_t PB_MotorTempL = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Temp_LoaderL.PageGroup"].toUInt(); // 电机温度显示数据
// 从32位数据中提取16位百分比值高16位和低16位拆分
uint16_t PercentageCurLU = static_cast<uint16_t>(PB_GroupL1 >> 16); // U相电流百分比高16位
uint16_t PercentageCurLV = static_cast<uint16_t>(PB_GroupL1 & 0xFFFF); // V相电流百分比低16位
uint16_t PercentageCurLW = static_cast<uint16_t>(PB_GroupL2 >> 16); // W相电流百分比高16位
uint16_t PercentageTmpColorL = static_cast<uint16_t>(PB_GroupL2 & 0xFFFF); // 温度颜色百分比低16位
uint16_t PercentageMotorTempL= static_cast<uint16_t>(PB_MotorTempL >> 16); // 电机温度百分比高16位
uint16_t ColorTempL = static_cast<uint16_t>(PB_MotorTempL & 0xFFFF); // 温度颜色值低16位
// 解析颜色值(从百分比中提取个位、十位、百位)
uint8_t ColorLU = (PercentageTmpColorL / 10) % 10; // U相颜色值十位
uint8_t ColorLV = (PercentageTmpColorL / 100) % 10; // V相颜色值百位
uint8_t ColorLW = PercentageTmpColorL % 10; // W相颜色值个位
// 设置进度条显示(电流和温度)
SetProgressBar(ui->PB_CurL_1, PercentageCurLU, ColorLU, glMotorCurColor); // U相电流进度条
SetProgressBar(ui->PB_CurL_2, PercentageCurLV, ColorLV, glMotorCurColor); // V相电流进度条
SetProgressBar(ui->PB_CurL_3, PercentageCurLW, ColorLW, glMotorCurColor); // W相电流进度条
SetProgressBar(ui->PB_TempL, PercentageMotorTempL, ColorTempL, glMotorTempColor); // 电机温度进度条
// 在LCD上显示实际测量值电流和温度
ui->LCD_CurL_1->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_U"].toReal()); // U相电流实际值
ui->LCD_CurL_2->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_V"].toReal()); // V相电流实际值
ui->LCD_CurL_3->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_W"].toReal()); // W相电流实际值
ui->LCD_TempL->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered_Temp"].toReal()); // 电机温度实际值
/**************************************************************************************/
/************************************* 电机基本信息 *************************************/
// 从OPC节点获取切割设备电机相关的状态数据32位无符号整数
uint32_t PB_GroupR1 = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Curr_LoaderR.PageGroup1"].toUInt(); // 电流显示组1数据
uint32_t PB_GroupR2 = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Curr_LoaderR.PageGroup2"].toUInt(); // 电流显示组2数据
uint32_t PB_MotorTempR = gOPC_NodeValue["ns=6;s=::AsGlobalPV:PB_Temp_LoaderR.PageGroup"].toUInt(); // 电机温度显示数据
// 从32位数据中提取16位百分比值高16位和低16位拆分
uint16_t PercentageCurRU = static_cast<uint16_t>(PB_GroupR1 >> 16); // U相电流百分比高16位
uint16_t PercentageCurRV = static_cast<uint16_t>(PB_GroupR1 & 0xFFFF); // V相电流百分比低16位
uint16_t PercentageCurRW = static_cast<uint16_t>(PB_GroupR2 >> 16); // W相电流百分比高16位
uint16_t PercentageTmpColorR = static_cast<uint16_t>(PB_GroupR2 & 0xFFFF); // 温度颜色百分比低16位
uint16_t PercentageMotorTempR= static_cast<uint16_t>(PB_MotorTempR >> 16); // 电机温度百分比高16位
uint16_t ColorTempR = static_cast<uint16_t>(PB_MotorTempR & 0xFFFF); // 温度颜色值低16位
// 解析颜色值(从百分比中提取个位、十位、百位)
uint8_t ColorRU = (PercentageTmpColorR / 10) % 10; // U相颜色值十位
uint8_t ColorRV = (PercentageTmpColorR / 100) % 10; // V相颜色值百位
uint8_t ColorRW = PercentageTmpColorR % 10; // W相颜色值个位
// 设置进度条显示(电流和温度)
SetProgressBar(ui->PB_CurR_1, PercentageCurRU, ColorRU, glMotorCurColor); // U相电流进度条
SetProgressBar(ui->PB_CurR_2, PercentageCurRV, ColorRV, glMotorCurColor); // V相电流进度条
SetProgressBar(ui->PB_CurR_3, PercentageCurRW, ColorRW, glMotorCurColor); // W相电流进度条
SetProgressBar(ui->PB_TempR, PercentageMotorTempR, ColorTempR, glMotorTempColor); // 电机温度进度条
// 在LCD上显示实际测量值电流和温度
ui->LCD_CurR_1->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_U"].toReal()); // U相电流实际值
ui->LCD_CurR_2->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_V"].toReal()); // V相电流实际值
ui->LCD_CurR_3->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_W"].toReal()); // W相电流实际值
ui->LCD_TempR->display(gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered_Temp"].toReal()); // 电机温度实际值
/**************************************************************************************/
/************************************* 启停条件信息 *************************************/
uint32_t SSConditions = gOPC_NodeValue["ns=6;s=::AsGlobalPV:StartStopConditions.Loader"].toUInt(); // 启停条件状态数据
// 更新32个启停条件状态标签的显示样式
for (int i = 0; i < 32; ++i)
{
// 根据索引查找对应的标签控件
QLabel* Label = findChild<QLabel*>(QString("Text_SSConditions_%1").arg(i));
// 如果找到标签
if (Label){
// 基础样式:默认背景图
QString StyleStr = "border-image: url(:/Frames/null.png);\n";
// 根据状态位设置不同颜色True/False对应不同样式
StyleStr += getBitOf32Data(SSConditions, i, false) ? TrueColor[i] + "\n" : FalseColor[i] + "\n";
// 应用样式到标签
Label->setStyleSheet(StyleStr);
}
}
/**************************************************************************************/
/************************************ 截割油缸压力信息 ***********************************/
SetProgressBar(ui->PB_1,ui->LCD_1,"PB_SprayFlow_Board.PageGroup","IN_Sersor.SprayFlow_Board");
/**************************************************************************************/
}
void P501_LoaderPage::TrailRefreshTimeOut(){
ui->CPW_L1->appendPoint(0, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_U"] .toReal());
ui->CPW_L1->appendPoint(1, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_V"] .toReal());
ui->CPW_L1->appendPoint(2, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered30_W"] .toReal());
ui->CPW_L2->appendPoint(0,gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderL.Filtered_Temp"] .toDouble());
ui->CPW_R1->appendPoint(0, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_U"] .toReal());
ui->CPW_R1->appendPoint(1, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_V"] .toReal());
ui->CPW_R1->appendPoint(2, gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered30_W"] .toReal());
ui->CPW_R2->appendPoint(0,gOPC_NodeValue["ns=6;s=::AsGlobalPV:IN_PhaseLoaderR.Filtered_Temp"] .toDouble());
}
void P501_LoaderPage::RotateDev(){
if(!gPageIndexStr.contains("P501"))
return;
mAngle = mAngle + 1;
if(mAngle > 360) mAngle =0;
mObjLoader->rotateArmToAbsoluteYAngle(DevName3D, mAngle);
}