GrabBag/Tools/CalibView/Src/CalibResultWidget.cpp

176 lines
5.4 KiB
C++
Raw 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 "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);
// 变换矩阵(左侧)
mainLayout->addWidget(createRotationGroup(), 1);
// 标定误差(右侧)
mainLayout->addWidget(createErrorGroup());
// 限制整体最大高度
setMaximumHeight(140);
}
QGroupBox* CalibResultWidget::createRotationGroup()
{
QGroupBox* group = new QGroupBox("变换矩阵 [R | T]", this);
QVBoxLayout* layout = new QVBoxLayout(group);
layout->setContentsMargins(4, 4, 4, 4);
layout->setSpacing(2);
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);
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;
};
layout->addWidget(createErrorLabel("平均误差", m_lblError, "font-weight: bold; color: red;"));
layout->addWidget(createErrorLabel("最大误差", m_lblMaxError));
layout->addWidget(createErrorLabel("最小误差", m_lblMinError));
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));
}
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");
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));
}