手眼标定完善

This commit is contained in:
yiyi 2026-02-22 00:10:46 +08:00
parent 11c615d0c9
commit ce4bd9348a
8 changed files with 2073 additions and 1741 deletions

46
GrabBagPrj/CalibView.iss Normal file
View File

@ -0,0 +1,46 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "手眼标定工具"
#define MyAppVersion "1.0.0"
#define MyAppPublisher ""
#define MyAppURL ""
#define MyAppExeName "CalibView.exe"
#define MyProgramPath ".\buildwin\CalibView"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{F8A7B6C5-D4E3-4F2A-9B1C-0D8E7F6A5B4C}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}_V{#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableProgramGroupPage=yes
OutputBaseFilename={#MyAppName}V{#MyAppVersion}
OutputDir=..\Publish
Compression=lzma
SolidCompression=yes
[Languages]
Name: "default"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "{#MyProgramPath}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runascurrentuser
[Code]

View File

@ -0,0 +1,34 @@
@echo off
setlocal
set PRJ_PATH=c:\project\QT\GrabBag\GrabBagPrj
if not exist "%PRJ_PATH%\buildwin\CalibView" mkdir "%PRJ_PATH%\buildwin\CalibView"
cd /d "%PRJ_PATH%\buildwin\CalibView"
powershell -Command "Remove-Item * -Recurse -Force"
copy "..\..\build\Tools\CalibView\release\CalibView.exe" .\
:: VzNLSDK DLL
copy "..\..\SDK\Device\VzNLSDK\Windows\x64\Release\VzKernel.dll" .\
copy "..\..\SDK\Device\VzNLSDK\Windows\x64\Release\VzNLDetect.dll" .\
copy "..\..\SDK\Device\VzNLSDK\Windows\x64\Release\VzNLGraphics.dll" .\
copy "..\..\SDK\Device\VzNLSDK\Windows\x64\Release\VzLog.dll" .\
copy "..\..\SDK\Device\VzNLSDK\Windows\x64\Release\libViEyeApi.dll" .\
:: OpenCV DLL
copy "..\..\SDK\OpenCV320\Windows\vc14\Release\opencv_world320.dll" .\
"C:\tools\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe" "CalibView.exe"
cd ..\..
set ISCC_PATH=C:\Program Files (x86)\Inno Setup 6\ISCC.exe
"%ISCC_PATH%" "CalibView.iss"
echo "finish"
endlocal

View File

@ -9,7 +9,7 @@ cd /d "%PRJ_PATH%\buildwin\CloudView"
powershell -Command "Remove-Item * -Recurse -Force"
copy "..\..\build\Tools\CloudView\release\CloudView.exe" .\
copy "..\..\build\Utils\CloudView\release\CloudView.exe" .\
"C:\tools\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe" "CloudView.exe"

View File

@ -1,200 +1,215 @@
#ifndef CALIBDATAWIDGET_H
#define CALIBDATAWIDGET_H
#include <QWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QComboBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <vector>
#include "HandEyeCalibTypes.h"
/**
* @brief
* Eye-To-HandEye-In-Hand TCP
*/
class CalibDataWidget : public QWidget
{
Q_OBJECT
public:
explicit CalibDataWidget(QWidget* parent = nullptr);
~CalibDataWidget() override;
/**
* @brief Eye-To-Hand
*/
void getEyeToHandData(std::vector<HECPoint3D>& eyePoints,
std::vector<HECPoint3D>& robotPoints) const;
/**
* @brief Eye-In-Hand
*/
void getEyeInHandData(std::vector<HECEyeInHandData>& calibData) const;
/**
* @brief
*/
HECCalibrationType getCalibType() const;
/**
* @brief
*/
void clearAll();
/**
* @brief
*/
void setRobotInput(double x, double y, double z, double rx, double ry, double rz);
/**
* @brief Eye-To-Hand
*/
void setCameraInput(double x, double y, double z, double rx, double ry, double rz);
/**
* @brief TCP
*/
HECTCPCalibData getTCPCalibData() const;
signals:
/**
* @brief
*/
void calibTypeChanged(HECCalibrationType type);
/**
* @brief Eye-To-Hand
*/
void requestEyeToHandCalib();
/**
* @brief Eye-In-Hand
*/
void requestEyeInHandCalib();
/**
* @brief TCP
*/
void requestTCPCalib();
private slots:
/**
* @brief
*/
void onCalibTypeChanged(int index);
/**
* @brief TCP 3-DOF / 6-DOF
*/
void onTCPModeChanged(int index);
/**
* @brief TCP
*/
void onTCPAddRow();
/**
* @brief TCP
*/
void onTCPRemoveRow();
private:
/**
* @brief
*/
void setupUI();
/**
* @brief Eye-To-Hand
*/
QWidget* createEyeToHandGroup();
/**
* @brief Eye-In-Hand
*/
QWidget* createEyeInHandGroup();
/**
* @brief TCP
*/
QWidget* createTCPCalibGroup();
/**
* @brief
*/
void updateTableVisibility();
// 标定模式选择
QComboBox* m_cbCalibType;
// Eye-To-Hand 数据表格
QTableWidget* m_tableEyeToHand;
QWidget* m_groupEyeToHand;
// Eye-In-Hand 数据表格
QTableWidget* m_tableEyeInHand;
QWidget* m_groupEyeInHand;
// Eye-To-Hand 内联按钮
QPushButton* m_btnEyeToHandAddRow;
QPushButton* m_btnEyeToHandDeleteRow;
QPushButton* m_btnEyeToHandCalib;
// Eye-In-Hand 内联按钮
QPushButton* m_btnEyeInHandAddRow;
QPushButton* m_btnEyeInHandDeleteRow;
QPushButton* m_btnEyeInHandCalib;
// TCP 标定相关
QWidget* m_groupTCPCalib;
QTableWidget* m_tableTCP;
QComboBox* m_tcpModeCombo;
QComboBox* m_tcpEulerOrderCombo;
QSpinBox* m_tcpRefPoseIndex;
QDoubleSpinBox* m_tcpWorldRx;
QDoubleSpinBox* m_tcpWorldRy;
QDoubleSpinBox* m_tcpWorldRz;
QGroupBox* m_tcpOrientationGroup;
QPushButton* m_tcpAddRowBtn;
QPushButton* m_tcpRemoveRowBtn;
QPushButton* m_btnTCPCalib;
// Eye-To-Hand 输入框
QDoubleSpinBox* m_inputEyeX;
QDoubleSpinBox* m_inputEyeY;
QDoubleSpinBox* m_inputEyeZ;
QDoubleSpinBox* m_inputRobotX;
QDoubleSpinBox* m_inputRobotY;
QDoubleSpinBox* m_inputRobotZ;
QPushButton* m_btnEyeToHandAddInput;
// Eye-In-Hand 输入框
QDoubleSpinBox* m_inputEndX;
QDoubleSpinBox* m_inputEndY;
QDoubleSpinBox* m_inputEndZ;
QDoubleSpinBox* m_inputEndRoll;
QDoubleSpinBox* m_inputEndPitch;
QDoubleSpinBox* m_inputEndYaw;
QDoubleSpinBox* m_inputCamX;
QDoubleSpinBox* m_inputCamY;
QDoubleSpinBox* m_inputCamZ;
QPushButton* m_btnEyeInHandAddInput;
// TCP 输入框
QDoubleSpinBox* m_inputTcpX;
QDoubleSpinBox* m_inputTcpY;
QDoubleSpinBox* m_inputTcpZ;
QDoubleSpinBox* m_inputTcpRx;
QDoubleSpinBox* m_inputTcpRy;
QDoubleSpinBox* m_inputTcpRz;
QPushButton* m_btnTcpAddInput;
};
#endif // CALIBDATAWIDGET_H
#ifndef CALIBDATAWIDGET_H
#define CALIBDATAWIDGET_H
#include <QWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QComboBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <vector>
#include "HandEyeCalibTypes.h"
/**
* @brief
* Eye-To-HandEye-In-Hand TCP
*/
class CalibDataWidget : public QWidget
{
Q_OBJECT
public:
explicit CalibDataWidget(QWidget* parent = nullptr);
~CalibDataWidget() override;
/**
* @brief Eye-To-Hand
*/
void getEyeToHandData(std::vector<HECPoint3D>& eyePoints,
std::vector<HECPoint3D>& robotPoints) const;
/**
* @brief Eye-In-Hand
*/
void getEyeInHandData(std::vector<HECEyeInHandData>& calibData) const;
/**
* @brief
*/
HECCalibrationType getCalibType() const;
/**
* @brief (0=EyeToHand, 1=EyeInHand, 2=TCP)
*/
int getCalibTypeIndex() const;
/**
* @brief
*/
void clearAll();
/**
* @brief
*/
void setRobotInput(double x, double y, double z, double rx, double ry, double rz);
/**
* @brief Eye-To-Hand
*/
void setCameraInput(double x, double y, double z, double rx, double ry, double rz);
/**
* @brief TCP
*/
HECTCPCalibData getTCPCalibData() const;
/**
* @brief INI
*/
void saveCalibData(const QString& filePath) const;
/**
* @brief INI
*/
void loadCalibData(const QString& filePath);
signals:
/**
* @brief
*/
void calibTypeChanged(HECCalibrationType type);
/**
* @brief Eye-To-Hand
*/
void requestEyeToHandCalib();
/**
* @brief Eye-In-Hand
*/
void requestEyeInHandCalib();
/**
* @brief TCP
*/
void requestTCPCalib();
private slots:
/**
* @brief
*/
void onCalibTypeChanged(int index);
/**
* @brief TCP 3-DOF / 6-DOF
*/
void onTCPModeChanged(int index);
/**
* @brief TCP
*/
void onTCPAddRow();
/**
* @brief TCP
*/
void onTCPRemoveRow();
private:
/**
* @brief
*/
void setupUI();
/**
* @brief Eye-To-Hand
*/
QWidget* createEyeToHandGroup();
/**
* @brief Eye-In-Hand
*/
QWidget* createEyeInHandGroup();
/**
* @brief TCP
*/
QWidget* createTCPCalibGroup();
/**
* @brief
*/
void updateTableVisibility();
// 标定模式选择
QComboBox* m_cbCalibType;
// Eye-To-Hand 数据表格
QTableWidget* m_tableEyeToHand;
QWidget* m_groupEyeToHand;
// Eye-In-Hand 数据表格
QTableWidget* m_tableEyeInHand;
QWidget* m_groupEyeInHand;
// Eye-To-Hand 内联按钮
QPushButton* m_btnEyeToHandAddRow;
QPushButton* m_btnEyeToHandDeleteRow;
QPushButton* m_btnEyeToHandCalib;
// Eye-In-Hand 内联按钮
QPushButton* m_btnEyeInHandAddRow;
QPushButton* m_btnEyeInHandDeleteRow;
QPushButton* m_btnEyeInHandCalib;
// TCP 标定相关
QWidget* m_groupTCPCalib;
QTableWidget* m_tableTCP;
QComboBox* m_tcpModeCombo;
QComboBox* m_tcpEulerOrderCombo;
QSpinBox* m_tcpRefPoseIndex;
QDoubleSpinBox* m_tcpWorldRx;
QDoubleSpinBox* m_tcpWorldRy;
QDoubleSpinBox* m_tcpWorldRz;
QGroupBox* m_tcpOrientationGroup;
QPushButton* m_tcpAddRowBtn;
QPushButton* m_tcpRemoveRowBtn;
QPushButton* m_btnTCPCalib;
// Eye-To-Hand 输入框
QDoubleSpinBox* m_inputEyeX;
QDoubleSpinBox* m_inputEyeY;
QDoubleSpinBox* m_inputEyeZ;
QDoubleSpinBox* m_inputRobotX;
QDoubleSpinBox* m_inputRobotY;
QDoubleSpinBox* m_inputRobotZ;
QPushButton* m_btnEyeToHandAddInput;
// Eye-In-Hand 输入框
QDoubleSpinBox* m_inputEndX;
QDoubleSpinBox* m_inputEndY;
QDoubleSpinBox* m_inputEndZ;
QDoubleSpinBox* m_inputEndRoll;
QDoubleSpinBox* m_inputEndPitch;
QDoubleSpinBox* m_inputEndYaw;
QDoubleSpinBox* m_inputCamX;
QDoubleSpinBox* m_inputCamY;
QDoubleSpinBox* m_inputCamZ;
QPushButton* m_btnEyeInHandAddInput;
// TCP 输入框
QDoubleSpinBox* m_inputTcpX;
QDoubleSpinBox* m_inputTcpY;
QDoubleSpinBox* m_inputTcpZ;
QDoubleSpinBox* m_inputTcpRx;
QDoubleSpinBox* m_inputTcpRy;
QDoubleSpinBox* m_inputTcpRz;
QPushButton* m_btnTcpAddInput;
};
#endif // CALIBDATAWIDGET_H

View File

@ -1,162 +1,172 @@
#ifndef CALIBVIEWMAINWINDOW_H
#define CALIBVIEWMAINWINDOW_H
#include <QMainWindow>
#include <QStatusBar>
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QPushButton>
#include <QTextEdit>
#include <memory>
#include "IHandEyeCalib.h"
class CalibDataWidget;
class CalibResultWidget;
class MainWindow; // RobotView::MainWindow
class VrEyeViewWidget;
/**
* @brief
* HandEyeCalib
*/
class CalibViewMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit CalibViewMainWindow(QWidget* parent = nullptr);
~CalibViewMainWindow() override;
signals:
/**
* @brief
*/
void calibrationCompleted(const HECCalibResult& result);
private slots:
/**
* @brief Eye-To-Hand
*/
void onEyeToHandCalib();
/**
* @brief Eye-In-Hand
*/
void onEyeInHandCalib();
/**
* @brief
*/
void onTransformTest();
/**
* @brief
*/
void onEulerTest();
/**
* @brief TCP
*/
void onTCPCalib();
/**
* @brief
*/
void onClearAll();
/**
* @brief
*/
void onSaveResult();
/**
* @brief
*/
void onLoadResult();
/**
* @brief RobotView
*/
void onOpenRobotView();
/**
* @brief RobotView TCP 姿
*/
void onRobotTcpPoseReceived(double x, double y, double z,
double rx, double ry, double rz);
/**
* @brief VrEyeView
*/
void onOpenVrEyeView();
/**
* @brief VrEyeView
*/
void onChessboardDetected(double x, double y, double z,
double rx, double ry, double rz);
private:
/**
* @brief
*/
void setupUI();
/**
* @brief
*/
void createMenuBar();
/**
* @brief
*/
QWidget* createRightPanel();
/**
* @brief
*/
void updateStatusBar(const QString& message);
/**
* @brief
*/
void appendLog(const QString& message);
// 标定实例
IHandEyeCalib* m_calib;
// 数据输入控件
CalibDataWidget* m_dataWidget;
// 结果显示控件
CalibResultWidget* m_resultWidget;
// 右侧面板 - 坐标变换测试
QDoubleSpinBox* m_sbTransformX;
QDoubleSpinBox* m_sbTransformY;
QDoubleSpinBox* m_sbTransformZ;
QPushButton* m_btnTransform;
// 右侧面板 - 欧拉角转换测试
QDoubleSpinBox* m_sbRoll;
QDoubleSpinBox* m_sbPitch;
QDoubleSpinBox* m_sbYaw;
QComboBox* m_cbEulerOrder;
QPushButton* m_btnEulerConvert;
// 右侧面板 - 日志
QTextEdit* m_logEdit;
// 当前标定结果
HECCalibResult m_currentResult;
bool m_hasResult;
// RobotView 窗口实例
MainWindow* m_robotView;
// VrEyeView 窗口实例
VrEyeViewWidget* m_vrEyeView;
};
#endif // CALIBVIEWMAINWINDOW_H
#ifndef CALIBVIEWMAINWINDOW_H
#define CALIBVIEWMAINWINDOW_H
#include <QMainWindow>
#include <QStatusBar>
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QPushButton>
#include <QTextEdit>
#include <memory>
#include "IHandEyeCalib.h"
class CalibDataWidget;
class CalibResultWidget;
class MainWindow; // RobotView::MainWindow
class VrEyeViewWidget;
/**
* @brief
* HandEyeCalib
*/
class CalibViewMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit CalibViewMainWindow(QWidget* parent = nullptr);
~CalibViewMainWindow() override;
signals:
/**
* @brief
*/
void calibrationCompleted(const HECCalibResult& result);
private slots:
/**
* @brief Eye-To-Hand
*/
void onEyeToHandCalib();
/**
* @brief Eye-In-Hand
*/
void onEyeInHandCalib();
/**
* @brief
*/
void onTransformTest();
/**
* @brief
*/
void onEulerTest();
/**
* @brief TCP
*/
void onTCPCalib();
/**
* @brief
*/
void onClearAll();
/**
* @brief
*/
void onSaveResult();
/**
* @brief
*/
void onLoadResult();
/**
* @brief
*/
void onSaveCalibData();
/**
* @brief
*/
void onLoadCalibData();
/**
* @brief RobotView
*/
void onOpenRobotView();
/**
* @brief RobotView TCP 姿
*/
void onRobotTcpPoseReceived(double x, double y, double z,
double rx, double ry, double rz);
/**
* @brief VrEyeView
*/
void onOpenVrEyeView();
/**
* @brief VrEyeView
*/
void onChessboardDetected(double x, double y, double z,
double rx, double ry, double rz);
private:
/**
* @brief
*/
void setupUI();
/**
* @brief
*/
void createMenuBar();
/**
* @brief
*/
QWidget* createRightPanel();
/**
* @brief
*/
void updateStatusBar(const QString& message);
/**
* @brief
*/
void appendLog(const QString& message);
// 标定实例
IHandEyeCalib* m_calib;
// 数据输入控件
CalibDataWidget* m_dataWidget;
// 结果显示控件
CalibResultWidget* m_resultWidget;
// 右侧面板 - 坐标变换测试
QDoubleSpinBox* m_sbTransformX;
QDoubleSpinBox* m_sbTransformY;
QDoubleSpinBox* m_sbTransformZ;
QPushButton* m_btnTransform;
// 右侧面板 - 欧拉角转换测试
QDoubleSpinBox* m_sbRoll;
QDoubleSpinBox* m_sbPitch;
QDoubleSpinBox* m_sbYaw;
QComboBox* m_cbEulerOrder;
QPushButton* m_btnEulerConvert;
// 右侧面板 - 日志
QTextEdit* m_logEdit;
// 当前标定结果
HECCalibResult m_currentResult;
bool m_hasResult;
// RobotView 窗口实例
MainWindow* m_robotView;
// VrEyeView 窗口实例
VrEyeViewWidget* m_vrEyeView;
};
#endif // CALIBVIEWMAINWINDOW_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2
Utils

@ -1 +1 @@
Subproject commit 7071da62403ea703981ffe77fff948266b66fdf3
Subproject commit 8c8dd5a5a26a316dbcd523eddfb8bd56727c62d2