GrabBag/Tools/CalibView/Src/CalibResultWidget.cpp

176 lines
5.4 KiB
C++
Raw Normal View History

2026-03-17 22:27:58 +08:00
#include "CalibResultWidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QHeaderView>
CalibResultWidget::CalibResultWidget(QWidget* parent)
: QWidget(parent)
, m_tableRotation(nullptr)
, m_lblError(nullptr)
, m_lblMaxError(nullptr)
, m_lblMinError(nullptr)
, m_hasResult(false)
{
setupUI();
}
CalibResultWidget::~CalibResultWidget()
{
}
void CalibResultWidget::setupUI()
{
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
2026-03-17 22:27:58 +08:00
// 变换矩阵(左侧)
mainLayout->addWidget(createRotationGroup(), 1);
2026-03-17 22:27:58 +08:00
// 标定误差(右侧)
2026-03-17 22:27:58 +08:00
mainLayout->addWidget(createErrorGroup());
// 限制整体最大高度
setMaximumHeight(140);
2026-03-17 22:27:58 +08:00
}
QGroupBox* CalibResultWidget::createRotationGroup()
{
QGroupBox* group = new QGroupBox("变换矩阵 [R | T]", this);
QVBoxLayout* layout = new QVBoxLayout(group);
layout->setContentsMargins(4, 4, 4, 4);
layout->setSpacing(2);
2026-03-17 22:27:58 +08:00
m_tableRotation = new QTableWidget(3, 4, this);
m_tableRotation->setHorizontalHeaderLabels({"Col 0", "Col 1", "Col 2", "T"});
m_tableRotation->setVerticalHeaderLabels({"Row 0", "Row 1", "Row 2"});
m_tableRotation->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
m_tableRotation->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
m_tableRotation->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 初始化为单位矩阵 + 零平移
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
QTableWidgetItem* item = new QTableWidgetItem(i == j ? "1.000000" : "0.000000");
item->setTextAlignment(Qt::AlignCenter);
m_tableRotation->setItem(i, j, item);
}
// 第4列T 向量,初始为 0
QTableWidgetItem* tItem = new QTableWidgetItem("0.000000");
tItem->setTextAlignment(Qt::AlignCenter);
m_tableRotation->setItem(i, 3, tItem);
}
layout->addWidget(m_tableRotation);
return group;
}
QGroupBox* CalibResultWidget::createErrorGroup()
{
QGroupBox* group = new QGroupBox("标定误差", this);
group->setMinimumWidth(280);
2026-03-17 22:27:58 +08:00
QHBoxLayout* layout = new QHBoxLayout(group);
layout->setContentsMargins(4, 4, 4, 4);
layout->setSpacing(8);
auto createErrorLabel = [this](const QString& title, QLabel*& valueLbl, const QString& style = "") {
QLabel* lbl = new QLabel(this);
lbl->setAlignment(Qt::AlignCenter);
lbl->setText(QString("%1\n0.0000 mm").arg(title));
if (!style.isEmpty()) {
lbl->setStyleSheet(style);
}
valueLbl = lbl;
return lbl;
};
2026-03-17 22:27:58 +08:00
layout->addWidget(createErrorLabel("平均误差", m_lblError, "font-weight: bold; color: red;"));
layout->addWidget(createErrorLabel("最大误差", m_lblMaxError));
layout->addWidget(createErrorLabel("最小误差", m_lblMinError));
2026-03-17 22:27:58 +08:00
return group;
}
void CalibResultWidget::updateRotationDisplay(const HECRotationMatrix& R)
{
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
QTableWidgetItem* item = m_tableRotation->item(i, j);
if (item) {
item->setText(QString::number(R.at(i, j), 'f', 6));
}
}
}
}
void CalibResultWidget::updateTranslationDisplay(const HECTranslationVector& T)
{
for (int i = 0; i < 3; ++i) {
QTableWidgetItem* item = m_tableRotation->item(i, 3);
if (item) {
item->setText(QString::number(T.at(i), 'f', 6));
}
}
}
void CalibResultWidget::showCalibResult(const HECCalibResult& result)
{
m_currentResult = result;
m_hasResult = true;
// 更新旋转矩阵
updateRotationDisplay(result.R);
// 更新平移向量
updateTranslationDisplay(result.T);
// 更新误差
m_lblError->setText(QString("平均误差\n%1 mm").arg(result.error, 0, 'f', 4));
m_lblMaxError->setText(QString("最大误差\n%1 mm").arg(result.maxError, 0, 'f', 4));
m_lblMinError->setText(QString("最小误差\n%1 mm").arg(result.minError, 0, 'f', 4));
2026-03-17 22:27:58 +08:00
}
void CalibResultWidget::clearAll()
{
// 重置旋转矩阵为单位矩阵
HECRotationMatrix identity;
updateRotationDisplay(identity);
// 重置平移向量
HECTranslationVector zero;
updateTranslationDisplay(zero);
// 重置误差
m_lblError->setText("平均误差\n0.0000 mm");
m_lblMaxError->setText("最大误差\n0.0000 mm");
m_lblMinError->setText("最小误差\n0.0000 mm");
2026-03-17 22:27:58 +08:00
m_hasResult = false;
}
void CalibResultWidget::showTCPCalibResult(const HECTCPCalibResult& result)
{
// 平移向量写入表格第4列
if (m_tableRotation->item(0, 3))
m_tableRotation->item(0, 3)->setText(QString::number(result.tx, 'f', 6));
if (m_tableRotation->item(1, 3))
m_tableRotation->item(1, 3)->setText(QString::number(result.ty, 'f', 6));
if (m_tableRotation->item(2, 3))
m_tableRotation->item(2, 3)->setText(QString::number(result.tz, 'f', 6));
// 仅位置模式时旋转矩阵标识为 N/A
if (result.rx == 0 && result.ry == 0 && result.rz == 0) {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
QTableWidgetItem* item = m_tableRotation->item(i, j);
if (item) {
item->setText("N/A");
}
}
}
}
// 误差显示
m_lblError->setText(QString("平均误差\n%1 mm").arg(result.residualError, 0, 'f', 4));
2026-03-17 22:27:58 +08:00
}