撕裂代码出版提交
This commit is contained in:
parent
032a0c017d
commit
9e3ba0b8c9
@ -14,8 +14,7 @@ win32-msvc {
|
||||
INCLUDEPATH += $$PWD/Presenter/Inc
|
||||
INCLUDEPATH += ../BeltTearingConfig/Inc
|
||||
|
||||
|
||||
INCLUDEPATH += ../../../VrNets/tcpClient/Inc
|
||||
INCLUDEPATH += ../../../VrNets/TCPClient/Inc
|
||||
INCLUDEPATH += ../../../VrUtils/Inc
|
||||
|
||||
# Link libraries
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
#define BELTTEARINGPRESENTER_H
|
||||
|
||||
#include "IVrBeltTearingConfig.h"
|
||||
#include "VrTcpClient.h"
|
||||
#include "IVrTCPClient.h"
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include "widgets/DeviceStatusWidget.h"
|
||||
|
||||
enum class ByteDataType {
|
||||
@ -22,7 +23,7 @@ public:
|
||||
explicit BeltTearingPresenter(QWidget* parent = nullptr);
|
||||
~BeltTearingPresenter();
|
||||
|
||||
void Init();
|
||||
void Init(); // 状态更新接口
|
||||
|
||||
QStringList getServerNames() const;
|
||||
QString getServerIp(const QString &serverName) const ;
|
||||
@ -49,13 +50,25 @@ private slots:
|
||||
void onDisconnected(const QString &serverName);
|
||||
void onDataReceived(const QString &serverName, const QByteArray &data);
|
||||
void onTcpError(const QString &serverName, const QString &error);
|
||||
void onReconnectTimer();
|
||||
|
||||
private:
|
||||
IStatusUpdate* m_statusUpdate = nullptr; // 状态更新接口
|
||||
IVrBeltTearingConfig * m_config = nullptr; // 配置接口
|
||||
DeviceStatusWidget* m_deviceStatusWidget = nullptr; // 设备状态控件
|
||||
QMap<QString, VrTcpClient*> m_tcpClients; // 服务器名称 -> TCP客户端映射
|
||||
QMap<QString, ServerInfo> m_serverInfos; // 服务器名称 -> 服务器信息映射
|
||||
private:
|
||||
// 静态回调函数(用于C接口)- 已弃用,使用lambda替代
|
||||
// static void tcpDataReceivedCallback(const char* pData, const int nLen);
|
||||
// static void tcpLinkStatusCallback(bool connected);
|
||||
|
||||
// 实例方法
|
||||
void handleTcpDataReceived(const QString &serverName, const char* pData, const int nLen);
|
||||
void handleTcpLinkStatus(const QString &serverName, bool connected);
|
||||
|
||||
private:
|
||||
IVrBeltTearingConfig * m_config = nullptr; // 配置接口
|
||||
IStatusUpdate* m_statusUpdate = nullptr; // 状态更新接口
|
||||
DeviceStatusWidget* m_deviceStatusWidget = nullptr; // 设备状态控件
|
||||
QMap<QString, IVrTCPClient*> m_tcpClients; // 服务器名称 -> TCP客户端映射
|
||||
QMap<QString, ServerInfo> m_serverInfos; // 服务器名称 -> 服务器信息映射
|
||||
QMap<QString, QTimer*> m_reconnectTimers; // 重连定时器
|
||||
QMap<QString, bool> m_connectionStatus; // 连接状态
|
||||
};
|
||||
|
||||
#endif // BELTTEARINGPRESENTER_H
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "BeltTearingPresenter.h"
|
||||
#include "VrTcpClient.h"
|
||||
#include "IVrTCPClient.h"
|
||||
#include "PathManager.h"
|
||||
#include "VrLog.h"
|
||||
#include <QDebug>
|
||||
@ -26,13 +26,19 @@ BeltTearingPresenter::BeltTearingPresenter(QWidget* parent)
|
||||
BeltTearingPresenter::~BeltTearingPresenter()
|
||||
{
|
||||
disconnectFromServer();
|
||||
|
||||
|
||||
// 删除所有TCP客户端
|
||||
for (auto it = m_tcpClients.begin(); it != m_tcpClients.end(); ++it) {
|
||||
delete it.value();
|
||||
IVrTCPClient::DestroyInstance(it.value());
|
||||
}
|
||||
m_tcpClients.clear();
|
||||
|
||||
|
||||
// 删除所有重连定时器
|
||||
for (auto it = m_reconnectTimers.begin(); it != m_reconnectTimers.end(); ++it) {
|
||||
delete it.value();
|
||||
}
|
||||
m_reconnectTimers.clear();
|
||||
|
||||
if (m_config) {
|
||||
delete m_config;
|
||||
m_config = nullptr;
|
||||
@ -79,25 +85,19 @@ bool BeltTearingPresenter::initializeConfig(const QString &configPath)
|
||||
|
||||
// 存储所有启用的服务器信息
|
||||
QList<DeviceInfo> devices;
|
||||
QStringList deviceAliases;
|
||||
|
||||
for (const auto &server : servers) {
|
||||
QString serverAliaseName = QString("%1_%2").arg(QString::fromStdString(server.name)).arg(CVrDateUtils::GetTimestamp());
|
||||
m_serverInfos[serverAliaseName] = server;
|
||||
|
||||
bool bRet = connectToServer(server, serverAliaseName);
|
||||
if(!bRet) continue;
|
||||
|
||||
// 添加到设备列表
|
||||
devices.append(DeviceInfo(QString::fromStdString(server.name), serverAliaseName, QString::fromStdString(server.ip), DeviceStatus::Offline, true));
|
||||
deviceAliases.append(serverAliaseName);
|
||||
LOG_DEBUG("Server configured: %s %s:%d \n", serverAliaseName.toStdString().c_str(), server.ip.c_str(), server.port);
|
||||
}
|
||||
|
||||
LOG_DEBUG("Init config finish. Found %d enabled servers \n", m_serverInfos.size());
|
||||
|
||||
// 收集设备别名列表
|
||||
QStringList deviceAliases;
|
||||
for (const auto &server : devices) {
|
||||
deviceAliases.append(server.alias);
|
||||
}
|
||||
|
||||
if(m_statusUpdate){
|
||||
m_statusUpdate->OnNeedShowImageCount(deviceAliases);
|
||||
@ -106,6 +106,11 @@ bool BeltTearingPresenter::initializeConfig(const QString &configPath)
|
||||
if (m_deviceStatusWidget) {
|
||||
m_deviceStatusWidget->setDevices(devices);
|
||||
}
|
||||
|
||||
// 连接
|
||||
for(size_t i = 0 ; i < devices.size() ; i++){
|
||||
connectToServer(servers[i], deviceAliases[i]);
|
||||
}
|
||||
|
||||
if (m_serverInfos.empty()) {
|
||||
LOG_WARNING("No enabled servers found\n");
|
||||
@ -122,38 +127,52 @@ bool BeltTearingPresenter::connectToServer(const ServerInfo &serverInfo, const Q
|
||||
|
||||
// 创建TCP客户端(如果不存在)
|
||||
if (!m_tcpClients.contains(targetServerName)) {
|
||||
VrTcpClient *client = new VrTcpClient();
|
||||
IVrTCPClient *client = IVrTCPClient::CreateInstance();
|
||||
if (!client) {
|
||||
LOG_ERROR("Failed to create TCP client for %s", targetServerName.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
m_tcpClients[targetServerName] = client;
|
||||
|
||||
// 连接TCP客户端的信号到Presenter的槽函数
|
||||
connect(client, &IVrTcpClient::connected, this, [this, targetServerName]() {
|
||||
onConnected(targetServerName);
|
||||
});
|
||||
connect(client, &IVrTcpClient::disconnected, this, [this, targetServerName]() {
|
||||
onDisconnected(targetServerName);
|
||||
});
|
||||
connect(client, &IVrTcpClient::connectionError, this, [this, targetServerName](const QString &error) {
|
||||
onTcpError(targetServerName, error);
|
||||
});
|
||||
connect(client, &IVrTcpClient::dataReceived, this, [this, targetServerName](const QByteArray &data) {
|
||||
onDataReceived(targetServerName, data);
|
||||
});
|
||||
m_connectionStatus[targetServerName] = false;
|
||||
|
||||
// 创建重连定时器
|
||||
QTimer *reconnectTimer = new QTimer(this);
|
||||
reconnectTimer->setSingleShot(true);
|
||||
reconnectTimer->setInterval(5000); // 5秒重连间隔
|
||||
connect(reconnectTimer, &QTimer::timeout, this, &BeltTearingPresenter::onReconnectTimer);
|
||||
m_reconnectTimers[targetServerName] = reconnectTimer;
|
||||
}
|
||||
|
||||
VrTcpClient *client = m_tcpClients[targetServerName];
|
||||
|
||||
// 设置自动重连
|
||||
client->setAutoReconnect(true);
|
||||
client->setReconnectInterval(5000); // 5秒重连间隔
|
||||
|
||||
|
||||
IVrTCPClient *client = m_tcpClients[targetServerName];
|
||||
|
||||
// 连接服务器
|
||||
bool success = client->connectToServer(QString::fromStdString(serverInfo.ip), serverInfo.port);
|
||||
|
||||
if (!success) {
|
||||
LOG_ERROR("Failed to initiate connection to %s", targetServerName.toStdString().c_str());
|
||||
int linkResult = client->LinkDevice(serverInfo.ip, serverInfo.port, true, // 启用自动重连
|
||||
[this, targetServerName](IVrTCPClient* pClient, bool connected, void* pParam) {
|
||||
this->handleTcpLinkStatus(targetServerName, connected);
|
||||
}, this
|
||||
);
|
||||
|
||||
LOG_DEBUG("connectToServer %s ret : %d \n", targetServerName.toStdString().c_str(), linkResult);
|
||||
|
||||
// 启动工作线程
|
||||
int workResult = client->StartWork(
|
||||
[this, targetServerName](IVrTCPClient* pClient, const char* pData, const int nLen, void* pParam) {
|
||||
this->handleTcpDataReceived(targetServerName, pData, nLen);
|
||||
}, this
|
||||
);
|
||||
|
||||
if (workResult != 0) {
|
||||
LOG_ERROR("Failed to start TCP client work thread for %s", targetServerName.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
|
||||
if (linkResult != 0) {
|
||||
LOG_ERROR("Failed to initiate connection to %s", targetServerName.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::disconnectFromServer(const QString &serverName)
|
||||
@ -161,14 +180,24 @@ void BeltTearingPresenter::disconnectFromServer(const QString &serverName)
|
||||
if (serverName.isEmpty()) {
|
||||
// 断开所有连接
|
||||
for (auto it = m_tcpClients.begin(); it != m_tcpClients.end(); ++it) {
|
||||
if (it.value()->isConnected()) {
|
||||
it.value()->disconnectFromServer();
|
||||
}
|
||||
it.value()->CloseDevice();
|
||||
m_connectionStatus[it.key()] = false;
|
||||
}
|
||||
|
||||
// 停止所有重连定时器
|
||||
for (auto it = m_reconnectTimers.begin(); it != m_reconnectTimers.end(); ++it) {
|
||||
it.value()->stop();
|
||||
}
|
||||
} else {
|
||||
// 断开指定服务器连接
|
||||
if (m_tcpClients.contains(serverName) && m_tcpClients[serverName]->isConnected()) {
|
||||
m_tcpClients[serverName]->disconnectFromServer();
|
||||
if (m_tcpClients.contains(serverName)) {
|
||||
m_tcpClients[serverName]->CloseDevice();
|
||||
m_connectionStatus[serverName] = false;
|
||||
}
|
||||
|
||||
// 停止重连定时器
|
||||
if (m_reconnectTimers.contains(serverName)) {
|
||||
m_reconnectTimers[serverName]->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,13 +205,13 @@ void BeltTearingPresenter::disconnectFromServer(const QString &serverName)
|
||||
bool BeltTearingPresenter::isConnected(const QString &serverName) const
|
||||
{
|
||||
if(serverName.isEmpty()) return false;
|
||||
|
||||
|
||||
QString targetServerName = serverName;
|
||||
|
||||
if (m_tcpClients.contains(targetServerName)) {
|
||||
return m_tcpClients[targetServerName]->isConnected();
|
||||
|
||||
if (m_connectionStatus.contains(targetServerName)) {
|
||||
return m_connectionStatus[targetServerName];
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -190,27 +219,27 @@ bool BeltTearingPresenter::sendData(const QByteArray &data, const QString &serve
|
||||
{
|
||||
if(serverName.isEmpty()) return false;
|
||||
QString targetServerName = serverName;
|
||||
|
||||
|
||||
if (!isConnected(targetServerName)) {
|
||||
LOG_ERROR("Not connected to server: %s", targetServerName.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (data.isEmpty()) {
|
||||
LOG_ERROR("Empty data to send");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!m_tcpClients.contains(targetServerName)) {
|
||||
LOG_ERROR("Server client not found: %s", targetServerName.toStdString().c_str());
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = m_tcpClients[targetServerName]->sendData(data);
|
||||
|
||||
bool success = m_tcpClients[targetServerName]->SendData(data.constData(), data.size());
|
||||
if (!success) {
|
||||
LOG_ERROR("Failed to send data to %s", targetServerName.toStdString().c_str());
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -249,6 +278,13 @@ void BeltTearingPresenter::onConnected(const QString &serverName)
|
||||
if (m_deviceStatusWidget) {
|
||||
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Online);
|
||||
}
|
||||
|
||||
// 通知主界面TCP客户端连接成功
|
||||
if (m_statusUpdate) {
|
||||
m_statusUpdate->OnServerConnected(serverName);
|
||||
m_statusUpdate->OnWorkStatusChanged(BeltTearingWorkStatus::Ready);
|
||||
m_statusUpdate->OnStatusUpdate(QString("TCP客户端 %1 连接成功").arg(serverName));
|
||||
}
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::onDisconnected(const QString &serverName)
|
||||
@ -257,6 +293,13 @@ void BeltTearingPresenter::onDisconnected(const QString &serverName)
|
||||
if (m_deviceStatusWidget) {
|
||||
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Offline);
|
||||
}
|
||||
|
||||
// 通知主界面TCP客户端连接断开
|
||||
if (m_statusUpdate) {
|
||||
m_statusUpdate->OnServerDisconnected(serverName);
|
||||
m_statusUpdate->OnWorkStatusChanged(BeltTearingWorkStatus::Disconnected);
|
||||
m_statusUpdate->OnStatusUpdate(QString("TCP客户端 %1 连接断开").arg(serverName));
|
||||
}
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::onDataReceived(const QString &serverName, const QByteArray &data)
|
||||
@ -319,10 +362,67 @@ void BeltTearingPresenter::onDataReceived(const QString &serverName, const QByte
|
||||
}
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::onTcpError(const QString &error, const QString &serverName)
|
||||
void BeltTearingPresenter::onTcpError(const QString &serverName, const QString &error)
|
||||
{
|
||||
if (m_deviceStatusWidget) {
|
||||
m_deviceStatusWidget->updateDeviceStatus(serverName, DeviceStatus::Error);
|
||||
}
|
||||
|
||||
// 通知主界面TCP客户端发生错误
|
||||
if (m_statusUpdate) {
|
||||
m_statusUpdate->OnWorkStatusChanged(BeltTearingWorkStatus::Error);
|
||||
m_statusUpdate->OnErrorOccurred(QString("TCP客户端 %1 错误: %2").arg(serverName, error));
|
||||
}
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::onReconnectTimer()
|
||||
{
|
||||
QTimer *timer = qobject_cast<QTimer*>(sender());
|
||||
if (!timer) return;
|
||||
|
||||
// 找到对应的服务器名称
|
||||
QString serverName;
|
||||
for (auto it = m_reconnectTimers.begin(); it != m_reconnectTimers.end(); ++it) {
|
||||
if (it.value() == timer) {
|
||||
serverName = it.key();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (serverName.isEmpty()) return;
|
||||
|
||||
// 如果当前没有连接,尝试重连
|
||||
if (!isConnected(serverName) && m_serverInfos.contains(serverName)) {
|
||||
const ServerInfo &serverInfo = m_serverInfos[serverName];
|
||||
LOG_DEBUG("Attempting to reconnect to %s", serverName.toStdString().c_str());
|
||||
connectToServer(serverInfo, serverName);
|
||||
}
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::handleTcpDataReceived(const QString &serverName, const char* pData, const int nLen)
|
||||
{
|
||||
if (!pData || nLen <= 0) return;
|
||||
|
||||
QByteArray data(pData, nLen);
|
||||
onDataReceived(serverName, data);
|
||||
}
|
||||
|
||||
void BeltTearingPresenter::handleTcpLinkStatus(const QString &serverName, bool connected)
|
||||
{
|
||||
m_connectionStatus[serverName] = connected;
|
||||
|
||||
if (connected) {
|
||||
// 停止重连定时器
|
||||
if (m_reconnectTimers.contains(serverName)) {
|
||||
m_reconnectTimers[serverName]->stop();
|
||||
}
|
||||
onConnected(serverName);
|
||||
} else {
|
||||
// 启动重连定时器
|
||||
if (m_reconnectTimers.contains(serverName)) {
|
||||
m_reconnectTimers[serverName]->start();
|
||||
}
|
||||
onDisconnected(serverName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -173,7 +173,7 @@ void MainWindow::onConfigSaved()
|
||||
void MainWindow::OnStatusUpdate(const QString &statusMessage)
|
||||
{
|
||||
statusBar()->showMessage(statusMessage);
|
||||
LOG_DEBUG("Status update: %s", statusMessage.toStdString().c_str());
|
||||
LOG_DEBUG("Status update: %s \n", statusMessage.toStdString().c_str());
|
||||
}
|
||||
|
||||
// 回调需要显示几个图像
|
||||
@ -211,14 +211,14 @@ void MainWindow::OnServerConnected(const QString &serverName)
|
||||
{
|
||||
QString message = QString("已连接到服务器: %1").arg(serverName);
|
||||
statusBar()->showMessage(message);
|
||||
LOG_DEBUG("%s", message.toStdString().c_str());
|
||||
LOG_DEBUG("%s \n", message.toStdString().c_str());
|
||||
}
|
||||
|
||||
void MainWindow::OnServerDisconnected(const QString &serverName)
|
||||
{
|
||||
QString message = QString("与服务器断开连接: %1").arg(serverName);
|
||||
statusBar()->showMessage(message);
|
||||
LOG_DEBUG("%s", message.toStdString().c_str());
|
||||
LOG_DEBUG("%s \n", message.toStdString().c_str());
|
||||
}
|
||||
|
||||
void MainWindow::OnWorkStatusChanged(BeltTearingWorkStatus status)
|
||||
@ -250,12 +250,12 @@ void MainWindow::OnWorkStatusChanged(BeltTearingWorkStatus status)
|
||||
|
||||
QString message = QString("工作状态: %1").arg(statusStr);
|
||||
statusBar()->showMessage(message);
|
||||
LOG_DEBUG("%s", message.toStdString().c_str());
|
||||
LOG_DEBUG("%s \n", message.toStdString().c_str());
|
||||
}
|
||||
|
||||
void MainWindow::OnErrorOccurred(const QString &errorMessage)
|
||||
{
|
||||
statusBar()->showMessage("错误: " + errorMessage);
|
||||
LOG_ERROR("Error occurred: %s", errorMessage.toStdString().c_str());
|
||||
LOG_ERROR("Error occurred: %s \n", errorMessage.toStdString().c_str());
|
||||
}
|
||||
|
||||
|
||||
@ -24,9 +24,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>34</y>
|
||||
<y>4</y>
|
||||
<width>341</width>
|
||||
<height>51</height>
|
||||
<height>111</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#define VERSION_H
|
||||
|
||||
#define BELT_TEARING_SERVER_VERSION_STRING "1.0.0"
|
||||
#define BELT_TEARING_SERVER_VERSION_BUILD "1"
|
||||
#define BELT_TEARING_SERVER_VERSION_BUILD "2"
|
||||
#define BELT_TEARING_SERVER_PRODUCT_NAME "BeltTearingServer"
|
||||
#define BELT_TEARING_SERVER_COMPANY_NAME "VisionRobot"
|
||||
#define BELT_TEARING_SERVER_COPYRIGHT "Copyright (C) 2024 VisionRobot. All rights reserved."
|
||||
|
||||
15
App/BeltTearing/BeltTearingServer/belttearingserver.service
Normal file
15
App/BeltTearing/BeltTearingServer/belttearingserver.service
Normal file
@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Belt Tearing Detection Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/belttearingserver
|
||||
Environment=LD_LIBRARY_PATH=/opt/sysroot/lib:/usr/lib:/lib
|
||||
ExecStart=/opt/belttearingserver/BeltTearingServer
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@ -986,7 +986,11 @@ int GrabBagPresenter::_OpenDevice(int cameraIndex, const char* cameraName, const
|
||||
IVrEyeDevice* pDevice = nullptr;
|
||||
IVrEyeDevice::CreateObject(&pDevice);
|
||||
int nRet = pDevice->InitDevice();
|
||||
ERR_CODE_RETURN(nRet);
|
||||
if(nRet != SUCCESS){
|
||||
delete pDevice;
|
||||
LOG_ERROR("InitDevice failed, error code: %d\n", nRet);
|
||||
ERR_CODE_RETURN(nRet);
|
||||
}
|
||||
|
||||
// 先设置状态回调
|
||||
nRet = pDevice->SetStatusCallback(&GrabBagPresenter::_StaticCameraNotify, this);
|
||||
|
||||
@ -5,13 +5,14 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += c++11
|
||||
# Add /utf-8 flag only for MSVC builds to enforce UTF-8 encoding
|
||||
win32-msvc {
|
||||
CONFIG += c++11
|
||||
QMAKE_CXXFLAGS += /utf-8
|
||||
}else{
|
||||
CONFIG += c++17
|
||||
}
|
||||
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
@ -41,6 +42,7 @@ SOURCES += \
|
||||
Presenter/Src/ConfigManager.cpp \
|
||||
Utils/Src/PathManager.cpp \
|
||||
devstatus.cpp \
|
||||
dialogalgoarg.cpp \
|
||||
dialogcamera.cpp \
|
||||
dialogcameralevel.cpp \
|
||||
main.cpp \
|
||||
@ -58,6 +60,7 @@ HEADERS += \
|
||||
IYLapWeldStatus.h \
|
||||
Version.h \
|
||||
devstatus.h \
|
||||
dialogalgoarg.h \
|
||||
dialogcamera.h \
|
||||
dialogcameralevel.h \
|
||||
mainwindow.h \
|
||||
@ -65,6 +68,7 @@ HEADERS += \
|
||||
|
||||
FORMS += \
|
||||
devstatus.ui \
|
||||
dialogalgoarg.ui \
|
||||
dialogcamera.ui \
|
||||
dialogcameralevel.ui \
|
||||
mainwindow.ui \
|
||||
@ -75,21 +79,21 @@ RESOURCES += \
|
||||
|
||||
|
||||
win32:CONFIG(debug, debug|release) {
|
||||
LIBS += -L../../../VrUtils/debug -lVrUtils
|
||||
LIBS += -L../../../CloudUtils/debug -lCloudUtils
|
||||
LIBS += -L../LapWeldConfig/debug -lLapWeldConfig
|
||||
LIBS += -L../../../VrEyeDevice/debug -lVrEyeDevice
|
||||
LIBS += -L../../../VrUtils/debug -lVrUtils
|
||||
LIBS += -L../../../CloudUtils/debug -lCloudUtils
|
||||
LIBS += -L../LapWeldConfig/debug -lLapWeldConfig
|
||||
LIBS += -L../../../VrEyeDevice/debug -lVrEyeDevice
|
||||
LIBS += -L../../../Module/ModbusTCPServer/debug -lModbusTCPServer
|
||||
LIBS += -L../../../Module/ShareMem/debug -lShareMem
|
||||
LIBS += -L../../../VrNets/debug -lVrModbus
|
||||
LIBS += -L../../../Module/ShareMem/debug -lShareMem
|
||||
LIBS += -L../../../VrNets/debug -lVrModbus
|
||||
}else:win32:CONFIG(release, debug|release){
|
||||
LIBS += -L../../../VrUtils/release -lVrUtils
|
||||
LIBS += -L../../../CloudUtils/release -lCloudUtils
|
||||
LIBS += -L../LapWeldConfig/release -lLapWeldConfig
|
||||
LIBS += -L../../../VrEyeDevice/release -lVrEyeDevice
|
||||
LIBS += -L../../../VrUtils/release -lVrUtils
|
||||
LIBS += -L../../../CloudUtils/release -lCloudUtils
|
||||
LIBS += -L../LapWeldConfig/release -lLapWeldConfig
|
||||
LIBS += -L../../../VrEyeDevice/release -lVrEyeDevice
|
||||
LIBS += -L../../../Module/ModbusTCPServer/release -lModbusTCPServer
|
||||
LIBS += -L../../../Module/ShareMem/release -lShareMem
|
||||
LIBS += -L../../../VrNets/release -lVrModbus
|
||||
LIBS += -L../../../Module/ShareMem/release -lShareMem
|
||||
LIBS += -L../../../VrNets/release -lVrModbus
|
||||
}else:unix:!macx {
|
||||
# Unix/Linux平台库链接(包括交叉编译)
|
||||
# 注意链接顺序:依赖关系从高到低
|
||||
@ -137,8 +141,8 @@ else:win32:CONFIG(debug, debug|release): {
|
||||
LIBS += -L$$PWD/../../../SDK/OpenCV320/Windows/vc14/Release -lopencv_world320
|
||||
}
|
||||
else:unix:!macx: {
|
||||
LIBS += -L$$PWD/../SDK/lapWeldDetection/Arm/aarch64 -llapWeldDetection
|
||||
LIBS += -L$$PWD/../SDK/OpenCV320/Arm/aarch64 -lopencv_core -lopencv_imgproc -lopencv_highgui
|
||||
LIBS += -L$$PWD/../../../SDK/lapWeldDetection/Arm/aarch64 -llapWeldDetection -lbaseAlgorithm
|
||||
LIBS += -L$$PWD/../../../SDK/OpenCV320/Arm/aarch64 -lopencv_core -lopencv_imgproc -lopencv_highgui
|
||||
}
|
||||
|
||||
# 添加libmodbus依赖
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
|
||||
@ -149,7 +149,7 @@ private:
|
||||
WorkStatus m_currentWorkStatus = WorkStatus::Error; // 当前工作状态
|
||||
int m_currentCameraIndex = 0; // 当前使用的相机编号
|
||||
|
||||
std::atomic<bool> m_bAlgoDetectThreadRunning = false;
|
||||
std::atomic<bool> m_bAlgoDetectThreadRunning{false};
|
||||
std::mutex m_algoDetectMutex;
|
||||
std::condition_variable m_algoDetectCondition;
|
||||
std::thread m_algoDetectThread; // 算法检测线程
|
||||
|
||||
@ -105,6 +105,7 @@ int DetectPresenter::DetectLapWeld(
|
||||
LOG_INFO("[Algo Thread] Tree Grow: yDeviation_max=%.1f, zDeviation_max=%.1f, maxLineSkipNum=%d, maxSkipDistance=%.1f, minLTypeTreeLen=%.1f, minVTypeTreeLen=%.1f\n",
|
||||
growParam.yDeviation_max, growParam.zDeviation_max, growParam.maxLineSkipNum,
|
||||
growParam.maxSkipDistance, growParam.minLTypeTreeLen, growParam.minVTypeTreeLen);
|
||||
}
|
||||
|
||||
// 准备平面校准参数
|
||||
SSG_planeCalibPara groundCalibPara;
|
||||
@ -155,6 +156,9 @@ int DetectPresenter::DetectLapWeld(
|
||||
std::vector<std::vector<SVzNL3DPoint>> objOps;
|
||||
sx_getLapWeldPostion(xyzData, cornerParam, growParam, lapWeldParam, groundCalibPara, objOps, &errCode);
|
||||
LOG_DEBUG("sx_getLapWeldPostion : res num %zd err : %d runtime: %.3fms \n", objOps.size(), errCode, oTimeUtils.GetElapsedTimeInMilliSec());
|
||||
for(size_t i = 0; i < objOps.size(); i++){
|
||||
LOG_DEBUG(" %d num : %zd \n", i, objOps[i].size());
|
||||
}
|
||||
ERR_CODE_RETURN(errCode);
|
||||
|
||||
// 从点云数据生成投影图像
|
||||
@ -162,35 +166,35 @@ int DetectPresenter::DetectLapWeld(
|
||||
|
||||
// 转换检测结果为UI显示格式(使用机械臂坐标系数据)
|
||||
for (size_t i = 0; i < objOps.size(); i++) {
|
||||
if (objOps[i].empty()) {
|
||||
continue;
|
||||
}
|
||||
const SVzNL3DPoint& obj = objOps[i][0]; // 使用第一个点作为参考
|
||||
|
||||
// 进行坐标转换:从算法坐标系转换到机械臂坐标系
|
||||
SVzNL3DPoint targetObj;
|
||||
targetObj.x = obj.x;
|
||||
targetObj.y = obj.y;
|
||||
targetObj.z = obj.z;
|
||||
|
||||
SVzNL3DPoint robotObj;
|
||||
CVrConvert::EyeToRobot(targetObj, robotObj, clibMatrix);
|
||||
|
||||
// 创建位置数据(使用转换后的机械臂坐标)
|
||||
LapWeldPosition pos;
|
||||
pos.x = robotObj.x; // 机械臂坐标X
|
||||
pos.y = robotObj.y; // 机械臂坐标Y
|
||||
pos.z = robotObj.z; // 机械臂坐标Z
|
||||
pos.roll = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
pos.pitch = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
pos.yaw = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
|
||||
detectionResult.positions.push_back(pos);
|
||||
|
||||
if(debugParam.enableDebug && debugParam.printDetailLog){
|
||||
LOG_INFO("[Algo Thread] Object %zu Eye Coords: X=%.2f, Y=%.2f, Z=%.2f\n", i, obj.x, obj.y, obj.z);
|
||||
LOG_INFO("[Algo Thread] Object %zu Robot Coords: X=%.2f, Y=%.2f, Z=%.2f, Roll=%.2f, Pitch=%.2f, Yaw=%.2f\n",
|
||||
i, pos.x, pos.y, pos.z, pos.roll, pos.pitch, pos.yaw);
|
||||
|
||||
for(size_t j = 0; j < objOps[i].size(); j++){
|
||||
const SVzNL3DPoint& obj = objOps[i][j];
|
||||
|
||||
// 进行坐标转换:从算法坐标系转换到机械臂坐标系
|
||||
SVzNL3DPoint targetObj;
|
||||
targetObj.x = obj.x;
|
||||
targetObj.y = obj.y;
|
||||
targetObj.z = obj.z;
|
||||
|
||||
SVzNL3DPoint robotObj;
|
||||
CVrConvert::EyeToRobot(targetObj, robotObj, clibMatrix);
|
||||
|
||||
// 创建位置数据(使用转换后的机械臂坐标)
|
||||
LapWeldPosition pos;
|
||||
pos.x = robotObj.x; // 机械臂坐标X
|
||||
pos.y = robotObj.y; // 机械臂坐标Y
|
||||
pos.z = robotObj.z; // 机械臂坐标Z
|
||||
pos.roll = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
pos.pitch = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
pos.yaw = 0.0; // 搭接焊缝检测不提供姿态角
|
||||
|
||||
detectionResult.positions.push_back(pos);
|
||||
|
||||
if(debugParam.enableDebug && debugParam.printDetailLog){
|
||||
LOG_INFO("[Algo Thread] Object %zu Eye Coords: X=%.2f, Y=%.2f, Z=%.2f\n", i, obj.x, obj.y, obj.z);
|
||||
LOG_INFO("[Algo Thread] Object %zu Robot Coords: X=%.2f, Y=%.2f, Z=%.2f, Roll=%.2f, Pitch=%.2f, Yaw=%.2f\n",
|
||||
i, pos.x, pos.y, pos.z, pos.roll, pos.pitch, pos.yaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,4 +213,4 @@ int DetectPresenter::DetectLapWeld(
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,12 +23,20 @@ QString PathManager::GetCalibrationFilePath()
|
||||
QString PathManager::GetAppConfigDirectory()
|
||||
{
|
||||
QString configDir = "";
|
||||
// #ifdef _WIN32
|
||||
// // Windows系统:使用程序目录
|
||||
// configDir = GetProgramDirectory();
|
||||
// #else
|
||||
// // Linux系统使用用户配置目录
|
||||
// configDir = QDir::homePath() + "/.config/LapWeldApp/Config";
|
||||
// #endif
|
||||
// return configDir + "/../LapWeldApp/Config";
|
||||
#ifdef _WIN32
|
||||
// Windows系统:使用程序目录
|
||||
configDir = GetProgramDirectory();
|
||||
#else
|
||||
// Linux系统使用用户配置目录
|
||||
configDir = QDir::homePath() + "/.config/LapWeldApp/Config";
|
||||
// Linux系统:使用用户配置目录
|
||||
configDir = GetUserConfigDirectory();
|
||||
#endif
|
||||
return configDir + "/../LapWeldApp/Config";
|
||||
}
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
#define VERSION_H
|
||||
|
||||
|
||||
#define LAPWELD_VERSION_STRING "1.1.3"
|
||||
#define LAPWELD_VERSION_STRING "1.0.0"
|
||||
#define LAPWELD_BUILD_STRING "1"
|
||||
#define LAPWELD_FULL_VERSION_STRING "V1.1.3_1"
|
||||
#define LAPWELD_FULL_VERSION_STRING "V1.0.0_1"
|
||||
|
||||
// 获取版本信息的便捷函数
|
||||
inline const char* GetLapWeldVersion() {
|
||||
|
||||
102
App/LapWeld/LapWeldApp/dialogalgoarg.cpp
Normal file
102
App/LapWeld/LapWeldApp/dialogalgoarg.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "dialogalgoarg.h"
|
||||
#include "ui_dialogalgoarg.h"
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QFile>
|
||||
#include "PathManager.h"
|
||||
|
||||
DialogAlgoarg::DialogAlgoarg(IVrConfig* vrConfig, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::DialogAlgoarg)
|
||||
, m_vrConfig(vrConfig)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// 隐藏标题栏
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
|
||||
// 获取配置文件路径
|
||||
m_configFilePath = PathManager::GetConfigFilePath();
|
||||
|
||||
// 从配置文件加载数据到界面
|
||||
LoadConfigToUI();
|
||||
}
|
||||
|
||||
DialogAlgoarg::~DialogAlgoarg()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DialogAlgoarg::LoadConfigToUI()
|
||||
{
|
||||
if (!m_vrConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 加载配置文件
|
||||
m_configData = m_vrConfig->LoadConfig(m_configFilePath.toStdString());
|
||||
|
||||
// 将激光焊接参数加载到界面控件
|
||||
const VrLapWeldParam& lapWeldParam = m_configData.algorithmParams.lapWeldParam;
|
||||
|
||||
// 设置参数到界面
|
||||
ui->lineEdit_lapHeight->setText(QString::number(lapWeldParam.lapHeight));
|
||||
ui->lineEdit_weldMinLen->setText(QString::number(lapWeldParam.weldMinLen));
|
||||
ui->lineEdit_weldRefPoints->setText(QString::number(lapWeldParam.weldRefPoints));
|
||||
|
||||
// 设置扫描模式下拉框
|
||||
ui->comboBox_scanMode->setCurrentIndex(static_cast<int>(lapWeldParam.scanMode));
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
QMessageBox::critical(this, "错误", "加载配置文件失败!");
|
||||
}
|
||||
}
|
||||
|
||||
bool DialogAlgoarg::SaveConfigFromUI()
|
||||
{
|
||||
if (!m_vrConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 从界面控件读取参数
|
||||
VrLapWeldParam& lapWeldParam = m_configData.algorithmParams.lapWeldParam;
|
||||
|
||||
// 读取参数
|
||||
lapWeldParam.lapHeight = ui->lineEdit_lapHeight->text().toDouble();
|
||||
lapWeldParam.weldMinLen = ui->lineEdit_weldMinLen->text().toDouble();
|
||||
lapWeldParam.weldRefPoints = ui->lineEdit_weldRefPoints->text().toInt();
|
||||
|
||||
// 读取扫描模式
|
||||
lapWeldParam.scanMode = static_cast<WeldScanMode>(ui->comboBox_scanMode->currentIndex());
|
||||
|
||||
// 保存配置文件
|
||||
bool success = m_vrConfig->SaveConfig(m_configFilePath.toStdString(), m_configData);
|
||||
|
||||
return success;
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DialogAlgoarg::on_btn_camer_ok_clicked()
|
||||
{
|
||||
if (SaveConfigFromUI()) {
|
||||
QMessageBox::information(this, "成功", "配置保存成功!");
|
||||
accept();
|
||||
} else {
|
||||
QMessageBox::warning(this, "失败", "配置保存失败,请检查文件权限!");
|
||||
}
|
||||
}
|
||||
|
||||
void DialogAlgoarg::on_btn_camer_cancel_clicked()
|
||||
{
|
||||
// 直接关闭窗口,不保存任何更改
|
||||
reject();
|
||||
}
|
||||
36
App/LapWeld/LapWeldApp/dialogalgoarg.h
Normal file
36
App/LapWeld/LapWeldApp/dialogalgoarg.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef DIALOGALGOARG_H
|
||||
#define DIALOGALGOARG_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
#include "IVrConfig.h"
|
||||
|
||||
namespace Ui {
|
||||
class DialogAlgoarg;
|
||||
}
|
||||
|
||||
class DialogAlgoarg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogAlgoarg(IVrConfig* vrConfig, QWidget *parent = nullptr);
|
||||
~DialogAlgoarg();
|
||||
|
||||
private slots:
|
||||
void on_btn_camer_ok_clicked();
|
||||
void on_btn_camer_cancel_clicked();
|
||||
|
||||
private:
|
||||
void LoadConfigToUI();
|
||||
bool SaveConfigFromUI();
|
||||
|
||||
private:
|
||||
Ui::DialogAlgoarg *ui;
|
||||
IVrConfig* m_vrConfig;
|
||||
ConfigResult m_configData;
|
||||
QString m_configFilePath;
|
||||
};
|
||||
|
||||
#endif // DIALOGALGOARG_H
|
||||
265
App/LapWeld/LapWeldApp/dialogalgoarg.ui
Normal file
265
App/LapWeld/LapWeldApp/dialogalgoarg.ui
Normal file
@ -0,0 +1,265 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogAlgoarg</class>
|
||||
<widget class="QWidget" name="DialogAlgoarg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>566</width>
|
||||
<height>412</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(25, 26, 28);</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="btn_camer_cancel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>340</x>
|
||||
<y>340</y>
|
||||
<width>111</width>
|
||||
<height>38</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/resource/dialog_cancel.png);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btn_camer_ok">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>340</y>
|
||||
<width>111</width>
|
||||
<height>38</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">image: url(:/resource/dialog_ok.png);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_camera_title">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>20</y>
|
||||
<width>491</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>算法参数</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>70</y>
|
||||
<width>451</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>激光焊接参数</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>22</x>
|
||||
<y>42</y>
|
||||
<width>411</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>搭接厚度</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>最小焊缝长度</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>参考点数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>扫描模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_lapHeight">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="inputMethodHints">
|
||||
<set>Qt::ImhFormattedNumbersOnly</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_weldMinLen">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="inputMethodHints">
|
||||
<set>Qt::ImhFormattedNumbersOnly</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_weldRefPoints">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<property name="inputMethodHints">
|
||||
<set>Qt::ImhDigitsOnly</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_scanMode">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>18</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(221, 225, 233);
|
||||
background-color: rgb(47, 48, 52);</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>垂直扫描</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>水平扫描</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>双向扫描</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -1,106 +1,106 @@
|
||||
#ifndef DialogCameraLevel_H
|
||||
#define DialogCameraLevel_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include "IVrEyeDevice.h"
|
||||
#include "LapWeldPresenter.h"
|
||||
#include "VZNL_Types.h"
|
||||
|
||||
|
||||
// #define LEVEL_DEBUG_MODE
|
||||
|
||||
namespace Ui {
|
||||
class DialogCameraLevel;
|
||||
}
|
||||
|
||||
class DialogCameraLevel : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogCameraLevel(QWidget *parent = nullptr);
|
||||
~DialogCameraLevel();
|
||||
|
||||
// Delete copy constructor and assignment operator due to atomic members
|
||||
DialogCameraLevel(const DialogCameraLevel&) = delete;
|
||||
DialogCameraLevel& operator=(const DialogCameraLevel&) = delete;
|
||||
|
||||
// 设置相机列表和presenter
|
||||
void setCameraList(const std::vector<std::pair<std::string, IVrEyeDevice*>>& cameraList,
|
||||
LapWeldPresenter* presenter);
|
||||
|
||||
private slots:
|
||||
void on_btn_apply_clicked();
|
||||
void on_btn_cancel_clicked();
|
||||
void on_combo_camera_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::DialogCameraLevel *ui;
|
||||
|
||||
// 相机列表和名称
|
||||
std::vector<std::pair<std::string, IVrEyeDevice*>> m_cameraList;
|
||||
LapWeldPresenter* m_presenter = nullptr;
|
||||
|
||||
// 扫描数据缓存
|
||||
std::vector<SVzNL3DLaserLine> m_scanDataCache;
|
||||
std::mutex m_scanDataMutex;
|
||||
|
||||
// 状态回调相关
|
||||
std::atomic<bool> m_swingFinished = false; // 摆动完成标志,同时表示扫描完成
|
||||
std::atomic<bool> m_callbackRestored = false;
|
||||
|
||||
// 初始化相机选择框
|
||||
void initializeCameraCombo();
|
||||
|
||||
// 执行相机调平
|
||||
bool performCameraLeveling();
|
||||
|
||||
// 直接使用相机接口进行扫描
|
||||
bool startCameraScan(int cameraIndex);
|
||||
bool stopCameraScan(int cameraIndex);
|
||||
|
||||
// 检测数据回调函数
|
||||
static void StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pUserData);
|
||||
void DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint);
|
||||
|
||||
// 状态回调函数
|
||||
static void StaticStatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
||||
void StatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
||||
|
||||
// 设置和恢复状态回调
|
||||
void setLevelingStatusCallback();
|
||||
void restorePresenterStatusCallback();
|
||||
|
||||
// 处理扫描到的地面数据进行调平计算
|
||||
bool calculatePlaneCalibration(double planeCalib[9], double& planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 清空扫描数据缓存
|
||||
void clearScanDataCache();
|
||||
|
||||
// Debug模式方法
|
||||
QString selectDebugDataFile();
|
||||
bool loadDebugDataAndSimulateScan(const QString& filePath);
|
||||
void simulateScanProcess();
|
||||
|
||||
// 更新调平结果显示
|
||||
void updateLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 保存调平结果到配置
|
||||
bool saveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9], int cameraIndex, const QString& cameraName);
|
||||
|
||||
// 加载相机标定数据
|
||||
bool loadCameraCalibrationData(int cameraIndex, const QString& cameraName,
|
||||
double planeCalib[9], double& planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 检查并显示相机标定状态
|
||||
void checkAndDisplayCalibrationStatus(int cameraIndex);
|
||||
};
|
||||
|
||||
#endif // DialogCameraLevel_H
|
||||
#ifndef DialogCameraLevel_H
|
||||
#define DialogCameraLevel_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QThread>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include "IVrEyeDevice.h"
|
||||
#include "LapWeldPresenter.h"
|
||||
#include "VZNL_Types.h"
|
||||
|
||||
|
||||
// #define LEVEL_DEBUG_MODE
|
||||
|
||||
namespace Ui {
|
||||
class DialogCameraLevel;
|
||||
}
|
||||
|
||||
class DialogCameraLevel : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogCameraLevel(QWidget *parent = nullptr);
|
||||
~DialogCameraLevel();
|
||||
|
||||
// Delete copy constructor and assignment operator due to atomic members
|
||||
DialogCameraLevel(const DialogCameraLevel&) = delete;
|
||||
DialogCameraLevel& operator=(const DialogCameraLevel&) = delete;
|
||||
|
||||
// 设置相机列表和presenter
|
||||
void setCameraList(const std::vector<std::pair<std::string, IVrEyeDevice*>>& cameraList,
|
||||
LapWeldPresenter* presenter);
|
||||
|
||||
private slots:
|
||||
void on_btn_apply_clicked();
|
||||
void on_btn_cancel_clicked();
|
||||
void on_combo_camera_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::DialogCameraLevel *ui;
|
||||
|
||||
// 相机列表和名称
|
||||
std::vector<std::pair<std::string, IVrEyeDevice*>> m_cameraList;
|
||||
LapWeldPresenter* m_presenter = nullptr;
|
||||
|
||||
// 扫描数据缓存
|
||||
std::vector<SVzNL3DLaserLine> m_scanDataCache;
|
||||
std::mutex m_scanDataMutex;
|
||||
|
||||
// 状态回调相关
|
||||
std::atomic<bool> m_swingFinished = false; // 摆动完成标志,同时表示扫描完成
|
||||
std::atomic<bool> m_callbackRestored = false;
|
||||
|
||||
// 初始化相机选择框
|
||||
void initializeCameraCombo();
|
||||
|
||||
// 执行相机调平
|
||||
bool performCameraLeveling();
|
||||
|
||||
// 直接使用相机接口进行扫描
|
||||
bool startCameraScan(int cameraIndex);
|
||||
bool stopCameraScan(int cameraIndex);
|
||||
|
||||
// 检测数据回调函数
|
||||
static void StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pUserData);
|
||||
void DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint);
|
||||
|
||||
// 状态回调函数
|
||||
static void StaticStatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
||||
void StatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
||||
|
||||
// 设置和恢复状态回调
|
||||
void setLevelingStatusCallback();
|
||||
void restorePresenterStatusCallback();
|
||||
|
||||
// 处理扫描到的地面数据进行调平计算
|
||||
bool calculatePlaneCalibration(double planeCalib[9], double& planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 清空扫描数据缓存
|
||||
void clearScanDataCache();
|
||||
|
||||
// Debug模式方法
|
||||
QString selectDebugDataFile();
|
||||
bool loadDebugDataAndSimulateScan(const QString& filePath);
|
||||
void simulateScanProcess();
|
||||
|
||||
// 更新调平结果显示
|
||||
void updateLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 保存调平结果到配置
|
||||
bool saveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9], int cameraIndex, const QString& cameraName);
|
||||
|
||||
// 加载相机标定数据
|
||||
bool loadCameraCalibrationData(int cameraIndex, const QString& cameraName,
|
||||
double planeCalib[9], double& planeHeight, double invRMatrix[9]);
|
||||
|
||||
// 检查并显示相机标定状态
|
||||
void checkAndDisplayCalibrationStatus(int cameraIndex);
|
||||
};
|
||||
|
||||
#endif // DialogCameraLevel_H
|
||||
|
||||
@ -492,6 +492,7 @@ void MainWindow::on_btn_stop_clicked()
|
||||
m_presenter->StopDetection();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_btn_camera_clicked()
|
||||
{
|
||||
// 检查是否有其他按钮已被选中
|
||||
@ -510,20 +511,65 @@ void MainWindow::on_btn_camera_clicked()
|
||||
setButtonSelectedState(ui->btn_camera, true);
|
||||
|
||||
// 使用新的相机列表获取功能
|
||||
|
||||
|
||||
// 如果对话框不存在,创建新的DialogCamera
|
||||
if (nullptr == ui_dialogCamera) {
|
||||
ui_dialogCamera = new DialogCamera(m_presenter->GetCameraList(), this);
|
||||
|
||||
|
||||
// 连接对话框关闭信号
|
||||
connect(ui_dialogCamera, &QDialog::finished, this, [this]() {
|
||||
setButtonSelectedState(ui->btn_camera, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ui_dialogCamera->show();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_btn_algo_config_clicked()
|
||||
{
|
||||
// 检查是否有其他按钮已被选中
|
||||
if (m_selectedButton != nullptr && m_selectedButton != ui->btn_algo_config) {
|
||||
updateStatusLog(tr("请先关闭当前打开的配置窗口"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查Presenter是否已初始化
|
||||
if (!m_presenter) {
|
||||
updateStatusLog(tr("系统未初始化,请等待初始化完成"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置当前按钮为选中状态
|
||||
setButtonSelectedState(ui->btn_algo_config, true);
|
||||
|
||||
// 获取配置对象
|
||||
IVrConfig* config = m_presenter->GetConfig();
|
||||
if (!config) {
|
||||
// 恢复按钮状态
|
||||
setButtonSelectedState(ui->btn_algo_config, false);
|
||||
// 设置白色字体的警告消息框
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("错误");
|
||||
msgBox.setText("配置模块未正确初始化!");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStyleSheet("QMessageBox { color: white; }");
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if(nullptr == ui_dialogConfig){
|
||||
ui_dialogConfig = new DialogAlgoarg(config, this);
|
||||
|
||||
// 连接对话框关闭信号
|
||||
connect(ui_dialogConfig, &QDialog::finished, this, [this]() {
|
||||
setButtonSelectedState(ui->btn_algo_config, false);
|
||||
});
|
||||
}
|
||||
ui_dialogConfig->show();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_btn_camera_levelling_clicked()
|
||||
{
|
||||
// 检查是否有其他按钮已被选中
|
||||
@ -643,7 +689,7 @@ void MainWindow::setButtonsEnabled(bool enabled)
|
||||
void MainWindow::setButtonImage(QPushButton* button, const QString& imagePath)
|
||||
{
|
||||
if (button) {
|
||||
QString styleSheet = QString("image: url(%1);").arg(imagePath);
|
||||
QString styleSheet = QString("image: url(%1);background-color: rgb(38, 40, 47);border: none;").arg(imagePath);
|
||||
button->setStyleSheet(styleSheet);
|
||||
}
|
||||
}
|
||||
@ -914,3 +960,5 @@ bool MainWindow::saveDetectionDataToFile(const QString& filePath, int cameraInde
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include "dialogcamera.h"
|
||||
#include "dialogalgoarg.h"
|
||||
#include "dialogcameralevel.h"
|
||||
#include "devstatus.h"
|
||||
#include "LapWeldPresenter.h"
|
||||
@ -79,6 +80,8 @@ private slots:
|
||||
|
||||
void on_btn_camera_clicked();
|
||||
|
||||
void on_btn_algo_config_clicked();
|
||||
|
||||
void on_btn_camera_levelling_clicked();
|
||||
|
||||
void on_btn_hide_clicked();
|
||||
@ -90,9 +93,11 @@ private slots:
|
||||
// 右键菜单相关槽函数
|
||||
void onSaveDetectionData();
|
||||
|
||||
|
||||
private:
|
||||
Ui::MainWindow * ui;
|
||||
DialogCamera* ui_dialogCamera = nullptr;
|
||||
DialogAlgoarg* ui_dialogConfig = nullptr;
|
||||
DialogCameraLevel* ui_dialogCameraLevel = nullptr;
|
||||
|
||||
// 业务逻辑处理类
|
||||
|
||||
@ -59,9 +59,9 @@ color: rgb(239, 241, 245);</string>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>34</y>
|
||||
<y>14</y>
|
||||
<width>341</width>
|
||||
<height>51</height>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
|
||||
@ -94,12 +94,12 @@ struct VrSlopeParam
|
||||
*/
|
||||
struct VrCornerParam
|
||||
{
|
||||
double cornerTh = 30; // 拐角阈值
|
||||
double cornerTh = 25; // 拐角阈值
|
||||
double scale = 4; // 计算方向角的窗口比例因子
|
||||
double minEndingGap = 20; // Y方向最小结束间隔
|
||||
double minEndingGap_z = 20; // Z方向最小结束间隔
|
||||
double minEndingGap = 6; // Y方向最小结束间隔
|
||||
double minEndingGap_z = 1.5; // Z方向最小结束间隔
|
||||
double jumpCornerTh_1 = 10; // 跳跃拐角阈值1
|
||||
double jumpCornerTh_2 = 30; // 跳跃拐角阈值2
|
||||
double jumpCornerTh_2 = 25; // 跳跃拐角阈值2
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -2,16 +2,10 @@
|
||||
<LapWeldConfig>
|
||||
<AlgorithmParams>
|
||||
|
||||
<!-- 离群点滤波参数 -->
|
||||
<OutlierFilterParam continuityTh="20.0" outlierTh="5" />
|
||||
|
||||
<!-- 角点特征参数 -->
|
||||
<CornerParam minEndingGap="20.0" minEndingGap_z="20.0" scale="4.0" cornerTh="30.0"
|
||||
jumpCornerTh_1="10.0" jumpCornerTh_2="30.0" />
|
||||
|
||||
<!-- 斜率参数 -->
|
||||
<SlopeParam LSlopeZWin="10.0" validSlopeH="5.0" minLJumpH="3.0" minEndingGap="2.0" />
|
||||
|
||||
<!-- 增长参数 -->
|
||||
<GrowParam maxLineSkipNum="5" yDeviation_max="1.0" maxSkipDistance="5.0"
|
||||
zDeviation_max="2.0" minLTypeTreeLen="30.0" minVTypeTreeLen="30.0" />
|
||||
|
||||
@ -19,10 +19,8 @@ SUBDIRS += ../CloudUtils/CloudUtils.pro
|
||||
SUBDIRS += ../App/GrabBag/GrabBag.pro
|
||||
|
||||
# 撕裂项目
|
||||
# SUBDIRS += ../App/BeltTearing/BeltTearing.pro
|
||||
SUBDIRS += ../App/BeltTearing/BeltTearing.pro
|
||||
|
||||
#焊接
|
||||
# SUBDIRS += ../App/LapWeld/LapWeld.pro
|
||||
|
||||
|
||||
SUBDIRS += ../App/LapWeld/LapWeld.pro
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ cd /d "%PRJ_PATH%\buildwin\BeltTearingApp"
|
||||
|
||||
powershell -Command "Remove-Item * -Recurse -Force"
|
||||
|
||||
copy "..\..\build\BeltTearingApp\release\BeltTearingApp.exe" .\
|
||||
copy "..\..\build\App\BeltTearing\BeltTearingApp\release\BeltTearingApp.exe" .\
|
||||
|
||||
"C:\tools\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe" "BeltTearingApp.exe"
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ PKG_NAME="BeltTearingServer"
|
||||
PKG_ARCH="arm64"
|
||||
|
||||
# 从Version.h文件中读取版本信息
|
||||
VERSION_FILE="../BeltTearingServer/Version.h"
|
||||
VERSION_FILE="../App/BeltTearing/BeltTearingServer/Version.h"
|
||||
|
||||
if [ -f "${VERSION_FILE}" ]; then
|
||||
# 读取版本号(从 BELT_TEARING_SERVER_VERSION_STRING 中提取)
|
||||
@ -54,14 +54,31 @@ mkdir -p ${PKG_PATH}/DEBIAN
|
||||
mkdir -p ${PKG_PATH}/usr/lib
|
||||
mkdir -p ${PKG_PATH}/etc/profile.d
|
||||
mkdir -p ${PKG_PATH}/opt/belttearingserver
|
||||
|
||||
mkdir -p ${PKG_PATH}/opt/sysroot/lib
|
||||
|
||||
echo "复制 Qt 运行时环境..."
|
||||
|
||||
#QT depend
|
||||
QT_PKG_PATH=/opt/firefly_qt5.15_arm64_20.04
|
||||
QT_LIB_PATH=/opt/sysroot/firefly-arm64-sysroot-20.04/lib/aarch64-linux-gnu
|
||||
|
||||
|
||||
cp -rfd ${QT_PKG_PATH}/ext ${PKG_PATH}/opt/firefly_qt5.15
|
||||
cp ${QT_PKG_PATH}/target_qtEnv.sh ${PKG_PATH}/etc/profile.d/
|
||||
|
||||
# 复制 Qt 库文件
|
||||
for libfile in ${QT_LIB_PATH}/*.so*; do
|
||||
# 获取文件名用于比较
|
||||
filename=$(basename "$libfile")
|
||||
|
||||
# 跳过 LLVM、flite、clang 和 X11 相关库文件
|
||||
if [[ "$filename" == *icu* ]]; then
|
||||
# 复制其他库文件,保持符号链接
|
||||
cp -rfd "$libfile" ${PKG_PATH}/opt/sysroot/lib/
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
echo "复制依赖库文件..."
|
||||
#depend
|
||||
cp -a ${CODE_PATH}/SDK/OpenCV320/Arm/aarch64/*opencv_core*.so* ${PKG_PATH}/usr/lib/
|
||||
@ -76,7 +93,10 @@ cp ${CODE_PATH}/SDK/VzNLSDK/Arm/aarch64/*.so ${PKG_PATH}/usr/lib/
|
||||
echo "复制 BeltTearingServer 内容到 /opt/..."
|
||||
|
||||
#APP
|
||||
cp ${CODE_PATH}/GrabBagPrj/buildarm/BeltTearingServer/BeltTearingServer ${PKG_PATH}/opt/belttearingserver/
|
||||
cp ${CODE_PATH}/GrabBagPrj/buildarm/App/BeltTearing/BeltTearingServer/BeltTearingServer ${PKG_PATH}/opt/belttearingserver/
|
||||
|
||||
#service
|
||||
cp ${CODE_PATH}/App/BeltTearing/BeltTearingServer/belttearingserver.service ${PKG_PATH}/opt/belttearingserver/
|
||||
|
||||
echo "生成 control 文件..."
|
||||
#control
|
||||
|
||||
@ -78,7 +78,6 @@ for libfile in ${QT_LIB_PATH}/*.so*; do
|
||||
cp -rfd "$libfile" ${PKG_PATH}/opt/sysroot/lib/
|
||||
continue
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
echo "复制依赖库文件..."
|
||||
|
||||
333
GrabBagPrj/pkg_lapweld.sh
Normal file
333
GrabBagPrj/pkg_lapweld.sh
Normal file
@ -0,0 +1,333 @@
|
||||
#!/bin/bash
|
||||
|
||||
#lapweld 版本配置
|
||||
PKG_NAME="LapWeld"
|
||||
PKG_ARCH="arm64"
|
||||
|
||||
# 从Version.h文件中读取版本信息
|
||||
VERSION_FILE="../App/LapWeld/LapWeldApp/Version.h"
|
||||
|
||||
if [ -f "${VERSION_FILE}" ]; then
|
||||
# 读取版本号(从 LAPWELD_VERSION_STRING 中提取)
|
||||
PKG_VERSION=$(grep '#define LAPWELD_VERSION_STRING' ${VERSION_FILE} | sed 's/.*"\(.*\)".*/\1/')
|
||||
# 读取构建号(从 LAPWELD_BUILD_STRING 中提取)
|
||||
BUILD_NUMBER=$(grep '#define LAPWELD_BUILD_STRING' ${VERSION_FILE} | sed 's/.*"\(.*\)".*/\1/')
|
||||
|
||||
echo "从 ${VERSION_FILE} 读取版本信息:"
|
||||
echo " 版本号: ${PKG_VERSION}"
|
||||
echo " 构建号: ${BUILD_NUMBER}"
|
||||
|
||||
# 如果读取失败,使用默认值
|
||||
if [ -z "${PKG_VERSION}" ]; then
|
||||
PKG_VERSION="1.0.0"
|
||||
echo "警告: 无法读取版本号,使用默认值: ${PKG_VERSION}"
|
||||
fi
|
||||
|
||||
if [ -z "${BUILD_NUMBER}" ]; then
|
||||
BUILD_NUMBER="1"
|
||||
echo "警告: 无法读取构建号,使用默认值: ${BUILD_NUMBER}"
|
||||
fi
|
||||
else
|
||||
# Version.h文件不存在时的默认值
|
||||
PKG_VERSION="1.0.0"
|
||||
BUILD_NUMBER="1"
|
||||
echo "警告: ${VERSION_FILE} 文件不存在,使用默认版本信息"
|
||||
echo " 版本号: ${PKG_VERSION}"
|
||||
echo " 构建号: ${BUILD_NUMBER}"
|
||||
fi
|
||||
|
||||
PKG_PATH=$HOME/LapWeldPkg
|
||||
CODE_PATH=../
|
||||
RELEASE_PATH=../Publish
|
||||
|
||||
echo "=========================================="
|
||||
echo "开始打包 LapWeld 应用程序 v${PKG_VERSION}..."
|
||||
echo "=========================================="
|
||||
|
||||
if [ -d "${PKG_PATH}" ];then
|
||||
echo "清理旧的打包目录..."
|
||||
rm -irf ${PKG_PATH}
|
||||
fi
|
||||
|
||||
#QT depend
|
||||
QT_PKG_PATH=/opt/firefly_qt5.15_arm64_20.04
|
||||
QT_LIB_PATH=/opt/sysroot/firefly-arm64-sysroot-20.04/lib/aarch64-linux-gnu
|
||||
|
||||
echo "创建打包目录结构..."
|
||||
mkdir -p ${PKG_PATH}/DEBIAN
|
||||
mkdir -p ${PKG_PATH}/etc/profile.d
|
||||
mkdir -p ${PKG_PATH}/etc/xdg/autostart
|
||||
mkdir -p ${PKG_PATH}/opt/sysroot/lib
|
||||
mkdir -p ${PKG_PATH}/usr/local/bin
|
||||
mkdir -p ${PKG_PATH}/usr/lib
|
||||
mkdir -p ${PKG_PATH}/usr/share/applications
|
||||
mkdir -p ${PKG_PATH}/usr/share/pixmaps
|
||||
|
||||
echo "复制 Qt 运行时环境..."
|
||||
cp -rfd ${QT_PKG_PATH}/ext ${PKG_PATH}/opt/firefly_qt5.15
|
||||
cp ${QT_PKG_PATH}/target_qtEnv.sh ${PKG_PATH}/etc/profile.d/
|
||||
|
||||
# 复制 Qt 库文件
|
||||
for libfile in ${QT_LIB_PATH}/*.so*; do
|
||||
# 获取文件名用于比较
|
||||
filename=$(basename "$libfile")
|
||||
|
||||
# 跳过 LLVM、flite、clang 和 X11 相关库文件
|
||||
if [[ "$filename" == *icu* ]]; then
|
||||
# 复制其他库文件,保持符号链接
|
||||
cp -rfd "$libfile" ${PKG_PATH}/opt/sysroot/lib/
|
||||
continue
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
echo "复制依赖库文件..."
|
||||
#depend
|
||||
cp -a ${CODE_PATH}/SDK/OpenCV320/Arm/aarch64/*opencv_core*.so* ${PKG_PATH}/usr/lib/
|
||||
cp -a ${CODE_PATH}/SDK/OpenCV320/Arm/aarch64/*opencv_imgproc*.so* ${PKG_PATH}/usr/lib/
|
||||
cp -a ${CODE_PATH}/SDK/OpenCV320/Arm/aarch64/*opencv_highgui*.so* ${PKG_PATH}/usr/lib/
|
||||
|
||||
cp ${CODE_PATH}/SDK/lapWeldDetection/Arm/aarch64/*.so ${PKG_PATH}/usr/lib/
|
||||
cp ${CODE_PATH}/SDK/VzNLSDK/Arm/aarch64/*.so ${PKG_PATH}/usr/lib/
|
||||
|
||||
echo "复制应用程序主文件..."
|
||||
#APP
|
||||
cp ${CODE_PATH}/GrabBagPrj/buildarm/App/LapWeld/LapWeldApp/LapWeldApp ${PKG_PATH}/usr/local/bin/
|
||||
|
||||
echo "复制应用程序图标..."
|
||||
#LOGO
|
||||
cp ${CODE_PATH}/App/LapWeld/LapWeldApp/resource/logo.png ${PKG_PATH}/usr/share/pixmaps/lapweld.png
|
||||
|
||||
echo "生成桌面自启动配置文件..."
|
||||
#desktop autostart configuration
|
||||
AUTOSTART_PATH=${PKG_PATH}/etc/xdg/autostart/lapweld.desktop
|
||||
cat > ${AUTOSTART_PATH} << EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=LapWeld
|
||||
Comment=LapWeld Application Auto Start
|
||||
Exec=/usr/local/bin/LapWeldApp
|
||||
Icon=/usr/share/pixmaps/lapweld.png
|
||||
Hidden=false
|
||||
NoDisplay=false
|
||||
X-GNOME-Autostart-enabled=true
|
||||
AutostartCondition=GNOME3 unless-session gnome
|
||||
EOF
|
||||
|
||||
echo "生成 control 文件..."
|
||||
#control
|
||||
CONTROL_PATH=${PKG_PATH}/DEBIAN/control
|
||||
echo "Package: ${PKG_NAME}" > ${CONTROL_PATH}
|
||||
echo "Version: ${PKG_VERSION}" >> ${CONTROL_PATH}
|
||||
echo "Section: lapweldapp" >> ${CONTROL_PATH}
|
||||
echo "Architecture: ${PKG_ARCH}" >> ${CONTROL_PATH}
|
||||
echo "Priority: optional" >> ${CONTROL_PATH}
|
||||
echo "Maintainer: LapWeld Team <support@lapweld.com>" >> ${CONTROL_PATH}
|
||||
echo "Description: lapweld app" >> ${CONTROL_PATH}
|
||||
|
||||
|
||||
|
||||
echo "生成安装后脚本..."
|
||||
#postinst install exec script
|
||||
POSTINST_PATH=${PKG_PATH}/DEBIAN/postinst
|
||||
cat > ${POSTINST_PATH} << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
echo "配置 LapWeld 应用程序..."
|
||||
|
||||
# 设置库文件路径
|
||||
echo "/usr/lib" > /etc/ld.so.conf.d/lapweld.conf
|
||||
echo "/opt/sysroot/lib/" >> /etc/ld.so.conf.d/lapweld.conf
|
||||
ldconfig
|
||||
|
||||
# 确保应用程序可执行
|
||||
chmod +x /usr/local/bin/LapWeldApp
|
||||
|
||||
# 配置端口映射 502 -> 5020
|
||||
echo "配置端口映射 502 -> 5020..."
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 502 -j REDIRECT --to-port 5020
|
||||
|
||||
# 检查并创建systemd服务确保重启后规则生效
|
||||
if [ ! -f /etc/systemd/system/lapweld-port-mapping.service ]; then
|
||||
echo "创建端口映射服务..."
|
||||
cat > /etc/systemd/system/lapweld-port-mapping.service << 'PORTEOF'
|
||||
[Unit]
|
||||
Description=LapWeld Port Mapping Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c 'iptables -t nat -A PREROUTING -p tcp --dport 502 -j REDIRECT --to-port 5020'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
PORTEOF
|
||||
|
||||
systemctl enable lapweld-port-mapping.service
|
||||
systemctl start lapweld-port-mapping.service
|
||||
else
|
||||
echo "端口映射服务已存在,跳过创建..."
|
||||
# 确保服务处于启用状态
|
||||
systemctl enable lapweld-port-mapping.service 2>/dev/null || true
|
||||
systemctl start lapweld-port-mapping.service 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 检查并创建当前用户的桌面快捷方式
|
||||
echo "检查当前用户的桌面快捷方式..."
|
||||
|
||||
# 获取当前执行安装的用户信息
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
# 如果是通过sudo执行的,获取真实用户
|
||||
current_user="$SUDO_USER"
|
||||
current_home=$(getent passwd "$current_user" | cut -d: -f6)
|
||||
else
|
||||
# 直接执行的情况
|
||||
current_user=$(whoami)
|
||||
current_home="$HOME"
|
||||
fi
|
||||
|
||||
echo "当前用户: $current_user"
|
||||
echo "用户主目录: $current_home"
|
||||
|
||||
# 检查多种可能的桌面目录名称
|
||||
desktop_dirs=("Desktop" "桌面" "desktop")
|
||||
desktop_dir=""
|
||||
desktop_shortcut=""
|
||||
|
||||
for dir_name in "${desktop_dirs[@]}"; do
|
||||
potential_dir="$current_home/$dir_name"
|
||||
if [ -d "$potential_dir" ]; then
|
||||
desktop_dir="$potential_dir"
|
||||
desktop_shortcut="$desktop_dir/lapweld.desktop"
|
||||
echo "找到桌面目录: $desktop_dir"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 检查是否找到桌面目录
|
||||
if [ -n "$desktop_dir" ]; then
|
||||
# 检查桌面上是否已有快捷方式
|
||||
if [ ! -f "$desktop_shortcut" ]; then
|
||||
echo "为当前用户创建桌面快捷方式..."
|
||||
# 复制桌面文件到用户桌面
|
||||
cp /usr/share/applications/lapweld.desktop "$desktop_shortcut"
|
||||
# 设置正确的所有者和权限
|
||||
chown $current_user:$current_user "$desktop_shortcut" 2>/dev/null || true
|
||||
chmod 755 "$desktop_shortcut"
|
||||
echo "已创建桌面快捷方式: $desktop_shortcut"
|
||||
else
|
||||
echo "桌面快捷方式已存在,跳过创建"
|
||||
fi
|
||||
else
|
||||
echo "当前用户没有找到桌面目录(Desktop/桌面/desktop),跳过桌面快捷方式创建"
|
||||
fi
|
||||
|
||||
echo "LapWeld 应用程序安装完成!"
|
||||
echo "应用程序将在用户登录桌面后自动启动。"
|
||||
echo "端口映射已配置:502 -> 5020"
|
||||
echo "桌面快捷方式已创建(如果用户有Desktop目录)"
|
||||
echo "如需立即启动,请运行: /usr/local/bin/LapWeldApp"
|
||||
echo "如需禁用自启动,请删除文件: ~/.config/autostart/lapweld.desktop"
|
||||
EOF
|
||||
|
||||
chmod +x ${POSTINST_PATH}
|
||||
|
||||
echo "生成卸载脚本..."
|
||||
#postrm uninstall exec script
|
||||
POSTRM_PATH=${PKG_PATH}/DEBIAN/postrm
|
||||
cat > ${POSTRM_PATH} << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
echo "卸载 LapWeld 应用程序..."
|
||||
|
||||
# 清理库文件配置
|
||||
rm -f /etc/ld.so.conf.d/lapweld.conf
|
||||
ldconfig
|
||||
|
||||
# 清理端口映射配置
|
||||
echo "清理端口映射配置..."
|
||||
systemctl stop lapweld-port-mapping.service 2>/dev/null || true
|
||||
systemctl disable lapweld-port-mapping.service 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/lapweld-port-mapping.service
|
||||
|
||||
# 清理iptables规则
|
||||
iptables -t nat -D PREROUTING -p tcp --dport 502 -j REDIRECT --to-port 5020 2>/dev/null || true
|
||||
|
||||
# 重新加载systemd
|
||||
systemctl daemon-reload
|
||||
|
||||
# 清理当前用户的桌面快捷方式
|
||||
echo "清理当前用户的桌面快捷方式..."
|
||||
|
||||
# 获取当前执行卸载的用户信息
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
# 如果是通过sudo执行的,获取真实用户
|
||||
current_user="$SUDO_USER"
|
||||
current_home=$(getent passwd "$current_user" | cut -d: -f6)
|
||||
else
|
||||
# 直接执行的情况
|
||||
current_user=$(whoami)
|
||||
current_home="$HOME"
|
||||
fi
|
||||
|
||||
# 检查多种可能的桌面目录名称并清理快捷方式
|
||||
desktop_dirs=("Desktop" "桌面" "desktop")
|
||||
shortcut_found=false
|
||||
|
||||
for dir_name in "${desktop_dirs[@]}"; do
|
||||
desktop_shortcut="$current_home/$dir_name/lapweld.desktop"
|
||||
if [ -f "$desktop_shortcut" ]; then
|
||||
echo "删除当前用户的桌面快捷方式: $desktop_shortcut"
|
||||
rm -f "$desktop_shortcut"
|
||||
echo "已删除桌面快捷方式: $desktop_shortcut"
|
||||
shortcut_found=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$shortcut_found" = false ]; then
|
||||
echo "当前用户没有找到桌面快捷方式,跳过清理"
|
||||
fi
|
||||
|
||||
echo "LapWeld 应用程序卸载完成!"
|
||||
echo "端口映射配置已清理"
|
||||
echo "桌面快捷方式已清理"
|
||||
echo "如需彻底清理自启动配置,请手动删除: ~/.config/autostart/lapweld.desktop"
|
||||
EOF
|
||||
|
||||
chmod +x ${POSTRM_PATH}
|
||||
|
||||
echo "生成桌面快捷方式..."
|
||||
#desktop
|
||||
DESKTOP_PATH=${PKG_PATH}/usr/share/applications/lapweld.desktop
|
||||
echo "[Desktop Entry]" > ${DESKTOP_PATH}
|
||||
echo "Version=${PKG_VERSION}" >> ${DESKTOP_PATH}
|
||||
echo "Name=LapWeld" >> ${DESKTOP_PATH}
|
||||
echo "Type=Application" >> ${DESKTOP_PATH}
|
||||
echo "Comment=LapWeld App" >> ${DESKTOP_PATH}
|
||||
echo "Terminal=false" >> ${DESKTOP_PATH}
|
||||
echo "Exec=/usr/local/bin/LapWeldApp" >> ${DESKTOP_PATH}
|
||||
echo "Icon=/usr/share/pixmaps/lapweld.png" >> ${DESKTOP_PATH}
|
||||
echo "Categories=Development;" >> ${DESKTOP_PATH}
|
||||
echo "GenericName=LapWeld App" >> ${DESKTOP_PATH}
|
||||
echo "Keywords=lapweld;app;" >> ${DESKTOP_PATH}
|
||||
echo "StartupNotify=true" >> ${DESKTOP_PATH}
|
||||
|
||||
echo "设置文件权限..."
|
||||
# 设置usr目录权限(不包括DEBIAN)
|
||||
chmod -R 755 ${PKG_PATH}/usr
|
||||
chmod -R 755 ${PKG_PATH}/etc
|
||||
chmod -R 755 ${PKG_PATH}/opt
|
||||
|
||||
echo "开始构建 DEB 包..."
|
||||
# 生成带时间戳和构建号的包文件名
|
||||
TIMESTAMP=$(date +%Y%m%d%H%M%S)
|
||||
DEB_FILENAME="${RELEASE_PATH}/${PKG_NAME}_${PKG_VERSION}_${BUILD_NUMBER}_${PKG_ARCH}_${TIMESTAMP}.deb"
|
||||
|
||||
fakeroot dpkg -b ${PKG_PATH} ${DEB_FILENAME}
|
||||
|
||||
echo "=========================================="
|
||||
echo "打包完成!"
|
||||
echo "生成的包文件: ${DEB_FILENAME}"
|
||||
echo "文件大小: $(ls -lh ${DEB_FILENAME} | awk '{print $5}')"
|
||||
echo "=========================================="
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -149,7 +149,8 @@ void _outputScanDataFile_vector_h(char* fileName, std::vector<std::vector<SVzNL3
|
||||
void _outputRGBDScanLapWeld_RGBD(
|
||||
char* fileName,
|
||||
std::vector<std::vector<SVzNL3DPosition>>& scanLines,
|
||||
std::vector< std::vector<SVzNL3DPoint>> weldOPs)
|
||||
std::vector< std::vector<SVzNL3DPoint>> weldOPs,
|
||||
bool outDebugInfo)
|
||||
{
|
||||
int lineNum = (int)scanLines.size();
|
||||
std::ofstream sw(fileName);
|
||||
@ -191,18 +192,38 @@ void _outputRGBDScanLapWeld_RGBD(
|
||||
for (int i = 0; i < linePtNum; i++)
|
||||
{
|
||||
SVzNL3DPosition* pt3D = &scanLines[line][i];
|
||||
if (pt3D->nPointIdx > 0)
|
||||
int kkk = 1;
|
||||
int featureType_v = pt3D->nPointIdx & 0xffff;
|
||||
int featureType_h = featureType_v >> 4;
|
||||
featureType_v &= 0xff;
|
||||
if (LINE_FEATURE_PEAK_TOP == featureType_v)
|
||||
if (true == outDebugInfo)
|
||||
{
|
||||
rgb = { 255, 97, 0 };
|
||||
size = 5;
|
||||
}
|
||||
else if (LINE_FEATURE_PEAK_TOP == featureType_h)
|
||||
{
|
||||
rgb = { 97, 255, 0 };
|
||||
size = 5;
|
||||
if (LINE_FEATURE_L_JUMP_H2L == featureType_v)
|
||||
{
|
||||
rgb = { 255, 97, 0 };
|
||||
size = 5;
|
||||
}
|
||||
else if (LINE_FEATURE_L_JUMP_L2H == featureType_v)
|
||||
{
|
||||
rgb = objColor[7];
|
||||
size = 5;
|
||||
}
|
||||
else if (LINE_FEATURE_L_JUMP_H2L == featureType_h)
|
||||
{
|
||||
rgb = objColor[6];
|
||||
size = 5;
|
||||
}
|
||||
else if (LINE_FEATURE_L_JUMP_L2H == featureType_h)
|
||||
{
|
||||
rgb = { 97, 255, 0 };
|
||||
size = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = { 200, 200, 200 };
|
||||
size = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -225,11 +246,10 @@ void _outputRGBDScanLapWeld_RGBD(
|
||||
linePtNum += (int)weldOPs[i].size();
|
||||
sw << "Line_" << lineNum << "_0_" << linePtNum + 1 << std::endl;
|
||||
|
||||
rgb = { 0, 0, 255 };
|
||||
rgb = { 255, 0, 0 };
|
||||
size = 25;
|
||||
for (int i = 0; i < weldNum; i++)
|
||||
{
|
||||
rgb = objColor[i % 8];
|
||||
for (int j = 0; j < (int)weldOPs[i].size(); j++)
|
||||
{
|
||||
float x = (float)weldOPs[i][j].x;
|
||||
@ -241,13 +261,37 @@ void _outputRGBDScanLapWeld_RGBD(
|
||||
}
|
||||
}
|
||||
//加一个点,用于跳过显示工具bug
|
||||
rgb = objColor[0];
|
||||
float x = (float)weldOPs[0][0].x;
|
||||
float y = (float)weldOPs[0][0].y;
|
||||
float z = (float)weldOPs[0][0].z;
|
||||
sw << "{" << x << "," << y << "," << z << "}-";
|
||||
sw << "{0,0}-{0,0}-";
|
||||
sw << "{" << rgb.r << "," << rgb.g << "," << rgb.b << "," << size << " }" << std::endl;
|
||||
|
||||
double exLen = 5.0;
|
||||
rgb = objColor[0];
|
||||
size = 3;
|
||||
for (int i = 0; i < weldNum; i++)
|
||||
{
|
||||
SVzNL3DPoint pt0 = weldOPs[i][0];
|
||||
SVzNL3DPoint pt1 = weldOPs[i].back();
|
||||
double len = sqrt(pow(pt0.x - pt1.x, 2) + pow(pt0.y - pt1.y, 2));
|
||||
double k = exLen / len;
|
||||
sw << "Poly_" << i << "_2" << std::endl;
|
||||
double x = -k * (pt1.x - pt0.x) + pt0.x;
|
||||
double y = -k * (pt1.y - pt0.y) + pt0.y;
|
||||
double z = -k * (pt1.z - pt0.z) + pt0.z;
|
||||
sw << "{" << (float)x << "," << (float)y << "," << (float)z << "}-";
|
||||
sw << "{0,0}-{0,0}-";
|
||||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||||
|
||||
x = -k * (pt0.x - pt1.x) + pt1.x;
|
||||
y = -k * (pt0.y - pt1.y) + pt1.y;
|
||||
z = -k * (pt0.z - pt1.z) + pt1.z;
|
||||
sw << "{" << x << "," << y << "," << z << "}-";
|
||||
sw << "{0,0}-{0,0}-";
|
||||
sw << "{" << (int)rgb.r << "," << (int)rgb.g << "," << (int)rgb.b << "," << size << "}" << std::endl;
|
||||
}
|
||||
}
|
||||
sw.close();
|
||||
}
|
||||
@ -655,7 +699,7 @@ void _convertToGridData(std::vector< std::vector<SVzNL3DPosition>>& scanLines,
|
||||
|
||||
#define CONVERT_TO_GRID 0
|
||||
#define TEST_COMPUTE_CALIB_PARA 0
|
||||
#define TEST_COMPUTE_GLOVE_POSITION 1
|
||||
#define TEST_COMPUTE_POSITION 1
|
||||
#define TEST_GROUP 1
|
||||
int main()
|
||||
{
|
||||
@ -665,7 +709,7 @@ int main()
|
||||
};
|
||||
|
||||
SVzNLRange fileIdx[TEST_GROUP] = {
|
||||
{0,6}
|
||||
{1,6}
|
||||
};
|
||||
|
||||
#if CONVERT_TO_GRID
|
||||
@ -720,7 +764,7 @@ int main()
|
||||
int kkk = 1;
|
||||
//行处理
|
||||
//调平,去除地面
|
||||
sx_lineDataR(scanData[i], calibPara.planeCalib, -1);// calibPara.planeHeight);
|
||||
sx_lineDataR(scanData[i], calibPara.planeCalib, -1); // calibPara.planeHeight);
|
||||
}
|
||||
//
|
||||
char calibFile[250];
|
||||
@ -734,7 +778,7 @@ int main()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_COMPUTE_GLOVE_POSITION
|
||||
#if TEST_COMPUTE_POSITION
|
||||
for (int grp = 0; grp <= 0; grp++)
|
||||
{
|
||||
SSG_planeCalibPara poseCalibPara;
|
||||
@ -771,7 +815,7 @@ int main()
|
||||
int kkk = 1;
|
||||
//行处理
|
||||
//调平,去除地面
|
||||
sx_lineDataR(scanLines[i], poseCalibPara.planeCalib, -1);// calibPara.planeHeight);
|
||||
sx_lineDataR(scanLines[i], poseCalibPara.planeCalib, -1);
|
||||
}
|
||||
#if 0
|
||||
char _out_file[256];
|
||||
@ -779,24 +823,26 @@ int main()
|
||||
int headNullLines = 0;
|
||||
_outputScanDataFile_vector(_out_file, scanLines, false, &headNullLines);
|
||||
#endif
|
||||
SSG_treeGrowParam growParam;
|
||||
growParam.maxLineSkipNum = 5;
|
||||
growParam.yDeviation_max = 1.0;
|
||||
growParam.maxSkipDistance = 5.0;
|
||||
growParam.zDeviation_max = 2;// algoParam.bagParam.bagH / 2; //袋子高度1/2
|
||||
growParam.minLTypeTreeLen = 30.0; //mm
|
||||
growParam.minVTypeTreeLen = 30.0; //mm
|
||||
SSG_cornerParam cornerParam;
|
||||
cornerParam.cornerTh =30; //45度角
|
||||
cornerParam.scale = 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||||
cornerParam.minEndingGap = 20;// algoParam.bagParam.bagW / 4;
|
||||
cornerParam.minEndingGap_z = 20; // algoParam.bagParam.bagH / 4;
|
||||
cornerParam.jumpCornerTh_1 = 10;
|
||||
cornerParam.jumpCornerTh_2 = 30;
|
||||
|
||||
SSX_lapWeldParam lapWeldParam;
|
||||
lapWeldParam.lapHeight = 2.0;
|
||||
lapWeldParam.weldMinLen = 2.0;
|
||||
lapWeldParam.lapHeight = 1.5;
|
||||
lapWeldParam.weldMinLen = 80.0;
|
||||
lapWeldParam.weldRefPoints = 2;
|
||||
lapWeldParam.scanMode = keSX_ScanMode_V;
|
||||
SSG_cornerParam cornerParam;
|
||||
cornerParam.cornerTh = 25; //45度角
|
||||
cornerParam.scale = 4; // algoParam.bagParam.bagH / 8; // 15; // algoParam.bagParam.bagH / 8;
|
||||
cornerParam.minEndingGap = 6;// algoParam.bagParam.bagW / 4;
|
||||
cornerParam.minEndingGap_z = lapWeldParam.lapHeight; // algoParam.bagParam.bagH / 4;
|
||||
cornerParam.jumpCornerTh_1 = 10;
|
||||
cornerParam.jumpCornerTh_2 = 25;
|
||||
SSG_treeGrowParam growParam;
|
||||
growParam.maxLineSkipNum = 10;
|
||||
growParam.yDeviation_max = 3.0;
|
||||
growParam.maxSkipDistance = 5.0;
|
||||
growParam.zDeviation_max = 1.0;// algoParam.bagParam.bagH / 2; //袋子高度1/2
|
||||
growParam.minLTypeTreeLen = lapWeldParam.weldMinLen; //mm
|
||||
growParam.minVTypeTreeLen = lapWeldParam.weldMinLen; //mm
|
||||
int errCode = 0;
|
||||
std::vector<std::vector<SVzNL3DPoint>> weldOps;
|
||||
sx_getLapWeldPostion(
|
||||
@ -804,6 +850,7 @@ int main()
|
||||
cornerParam,
|
||||
growParam,
|
||||
lapWeldParam,
|
||||
poseCalibPara,
|
||||
weldOps,
|
||||
&errCode);
|
||||
|
||||
@ -811,7 +858,7 @@ int main()
|
||||
printf("%s: %d(ms)!\n", _scan_file, (int)(t2 - t1));
|
||||
//输出测试结果
|
||||
sprintf_s(_scan_file, "%sresult\\LaserLine%d_result.txt", dataPath[grp], fidx);
|
||||
_outputRGBDScanLapWeld_RGBD(_scan_file, scanLines, weldOps);
|
||||
_outputRGBDScanLapWeld_RGBD(_scan_file, scanLines, weldOps, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -5,10 +5,11 @@
|
||||
|
||||
// 前向声明
|
||||
class CVrTCPClient;
|
||||
class IVrTCPClient;
|
||||
|
||||
// 回调函数类型定义
|
||||
using TCPRecvFunc = std::function<void(const char* pData, const int nLen)>;
|
||||
using LinkEventFunc = std::function<void(bool)>;
|
||||
using TCPRecvFunc = std::function<void(IVrTCPClient* pClient, const char* pData, const int nLen, void* pParam)>;
|
||||
using LinkEventFunc = std::function<void(IVrTCPClient* pClient, bool connected, void* pParam)>;
|
||||
|
||||
/**
|
||||
* @brief TCP客户端接口类
|
||||
@ -27,7 +28,7 @@ public:
|
||||
* @param linkFunc 连接状态回调函数
|
||||
* @return 0表示成功,其他值表示失败
|
||||
*/
|
||||
virtual int LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc) = 0;
|
||||
virtual int LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc, void* pParam) = 0;
|
||||
|
||||
/**
|
||||
* @brief 关闭设备连接
|
||||
@ -40,7 +41,7 @@ public:
|
||||
* @param fRecvFunc 接收数据回调函数
|
||||
* @return 0表示成功,其他值表示失败
|
||||
*/
|
||||
virtual int StartWork(TCPRecvFunc fRecvFunc) = 0;
|
||||
virtual int StartWork(TCPRecvFunc fRecvFunc, void* pParam) = 0;
|
||||
|
||||
/**
|
||||
* @brief 发送数据
|
||||
@ -61,4 +62,4 @@ public:
|
||||
* @param pInstance 待销毁的实例指针
|
||||
*/
|
||||
static void DestroyInstance(IVrTCPClient* pInstance);
|
||||
};
|
||||
};
|
||||
|
||||
@ -42,9 +42,10 @@ CVrTCPClient::~CVrTCPClient()
|
||||
}
|
||||
|
||||
|
||||
int CVrTCPClient::LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc)
|
||||
int CVrTCPClient::LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc, void* pParam)
|
||||
{
|
||||
m_fLinkcCallback = linkFunc;
|
||||
m_pLinkParam = pParam;
|
||||
m_sIp = sDevIP;
|
||||
m_nPort = nPort;
|
||||
|
||||
@ -53,7 +54,7 @@ int CVrTCPClient::LinkDevice(const std::string sDevIP, int nPort, bool bReLink,
|
||||
if (SUCCESS == nRet)
|
||||
{
|
||||
m_bLink = true;
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(true);
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(this, true, pParam);
|
||||
}
|
||||
|
||||
|
||||
@ -70,12 +71,13 @@ int CVrTCPClient::LinkDevice(const std::string sDevIP, int nPort, bool bReLink,
|
||||
|
||||
}
|
||||
|
||||
int CVrTCPClient::StartWork(TCPRecvFunc callbackFunc)
|
||||
int CVrTCPClient::StartWork(TCPRecvFunc fRecvFunc, void* pParam)
|
||||
{
|
||||
if (m_bRecv) return SUCCESS;
|
||||
|
||||
m_bRecv = true;
|
||||
m_fRecvCallback = callbackFunc;
|
||||
m_fRecvCallback = fRecvFunc;
|
||||
m_pWorkParam = pParam;
|
||||
std::thread recvThread(&CVrTCPClient::_RecvData, this);
|
||||
recvThread.detach();
|
||||
return SUCCESS;
|
||||
@ -170,16 +172,16 @@ void CVrTCPClient::_RecvData()
|
||||
|
||||
if (m_fRecvCallback)
|
||||
{
|
||||
m_fRecvCallback(recvData, recvLen);
|
||||
m_fRecvCallback(this, recvData, recvLen, m_pWorkParam);
|
||||
}
|
||||
}
|
||||
m_bRecvWorking = false;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸
|
||||
// 重新连接线程
|
||||
void CVrTCPClient::_ReLinkDevThread()
|
||||
{
|
||||
while (true)
|
||||
while (m_bRecvWorking)
|
||||
{
|
||||
if (m_bLink)
|
||||
{
|
||||
@ -188,7 +190,7 @@ void CVrTCPClient::_ReLinkDevThread()
|
||||
}
|
||||
|
||||
m_bLink = ( 0 == _ExecLinkDev(m_sIp, m_nPort) );
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(m_bLink);
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(this, m_bLink, m_pLinkParam);
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +203,7 @@ int CVrTCPClient::_ExecLinkDev(std::string sIP, int nPort)
|
||||
m_nSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (INVALID_SOCKET_VALUE == m_nSocket)
|
||||
{
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(false);
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(this, false, m_pLinkParam);
|
||||
return ERR_CODE(NET_ERR_CREAT_INIT);
|
||||
}
|
||||
|
||||
@ -219,7 +221,7 @@ int CVrTCPClient::_ExecLinkDev(std::string sIP, int nPort)
|
||||
if (SOCKET_ERROR_VALUE == nRet)
|
||||
{
|
||||
printf("dev connect err [%d] errno : %d\n", nRet, errno);
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(false);
|
||||
if (m_fLinkcCallback) m_fLinkcCallback(this, false, m_pLinkParam);
|
||||
return ERR_CODE(NET_ERR_CONNECT);
|
||||
}
|
||||
|
||||
|
||||
@ -47,13 +47,13 @@ public:
|
||||
~CVrTCPClient();
|
||||
|
||||
///
|
||||
int LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc) override;
|
||||
int LinkDevice(const std::string sDevIP, int nPort, bool bReLink, LinkEventFunc linkFunc, void* pParam) override;
|
||||
|
||||
/// ر豸
|
||||
int CloseDevice() override;
|
||||
|
||||
/// ʼܹ
|
||||
int StartWork(TCPRecvFunc fRecvFunc) override;
|
||||
int StartWork(TCPRecvFunc fRecvFunc, void* pParam) override;
|
||||
|
||||
///
|
||||
bool SendData(const char* pdata, const int nLen) override;
|
||||
@ -80,6 +80,10 @@ private:
|
||||
int _ExecLinkDev(std::string sIP, int nPort);
|
||||
|
||||
|
||||
|
||||
void* m_pLinkParam;
|
||||
void* m_pWorkParam;
|
||||
|
||||
socket_t m_nSocket;
|
||||
|
||||
bool m_bRecv;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user