250 lines
8.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

#include "StatorWorkpiecePositionPresenter.h"
#include "VrLog.h"
#include "VrError.h"
#include <QStringList>
namespace {
QString NumberField(double value)
{
return QString::number(value, 'f', 3);
}
QString IntField(int value)
{
return QString::number(value);
}
void AppendPoseFields(QStringList& fields, const WorkpiecePosition& position, int poseOutputOrder)
{
switch (poseOutputOrder) {
case POSE_ORDER_RPY:
fields << NumberField(position.roll) << NumberField(position.pitch) << NumberField(position.yaw);
break;
case POSE_ORDER_RYP:
fields << NumberField(position.roll) << NumberField(position.yaw) << NumberField(position.pitch);
break;
case POSE_ORDER_PRY:
fields << NumberField(position.pitch) << NumberField(position.roll) << NumberField(position.yaw);
break;
case POSE_ORDER_PYR:
fields << NumberField(position.pitch) << NumberField(position.yaw) << NumberField(position.roll);
break;
case POSE_ORDER_YRP:
fields << NumberField(position.yaw) << NumberField(position.roll) << NumberField(position.pitch);
break;
case POSE_ORDER_YPR:
fields << NumberField(position.yaw) << NumberField(position.pitch) << NumberField(position.roll);
break;
default:
fields << NumberField(position.roll) << NumberField(position.pitch) << NumberField(position.yaw);
break;
}
}
} // namespace
// 初始化TCP服务器
int StatorWorkpiecePositionPresenter::InitTCPServer()
{
LOG_DEBUG("Start initializing TCP server\n");
if (m_pTCPServer) {
LOG_WARNING("TCP server already initialized\n");
return 0;
}
// 创建TCP服务器协议实例
m_pTCPServer = new TCPServerProtocol();
// Register callbacks before Initialize() starts the listening thread.
// Otherwise an immediate client connection/request can be lost.
m_pTCPServer->SetConnectionCallback([this](bool connected) {
this->OnTCPConnectionChanged(connected);
});
m_pTCPServer->SetDetectionTriggerCallback([this](bool startWork, int cameraIndex, qint64 timestamp) {
return this->OnTCPDetectionTrigger(startWork, cameraIndex, timestamp);
});
m_pTCPServer->SetBinDetectionTriggerCallback([this](int cameraIndex, qint64 timestamp) {
return this->OnTCPBinDetectionTrigger(cameraIndex, timestamp);
});
// 从配置获取 TCP/IP 协议端口,默认 7800。
// Modbus TCP Server 端口固定为 5020不使用此配置项。
int port = 7800;
if (m_pConfigManager) {
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
const int configuredPort = configResult.plcRobotServerConfig.robotServerPort;
if (configuredPort > 0 && configuredPort <= 65535) {
port = configuredPort;
}
}
// 初始化TCP服务器
int nRet = m_pTCPServer->Initialize(port);
if (nRet != 0) {
LOG_ERROR("Failed to initialize TCP server, return code: %d\n", nRet);
delete m_pTCPServer;
m_pTCPServer = nullptr;
return nRet;
}
LOG_INFO("TCP server protocol initialized successfully on port %d\n", port);
return 0;
}
// TCP连接状态改变回调
void StatorWorkpiecePositionPresenter::OnTCPConnectionChanged(bool connected)
{
LOG_DEBUG("TCP connection status changed: %s\n", connected ? "connected" : "disconnected");
m_bTCPConnected.store(connected);
// 通知状态更新
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
if (connected) {
pStatus->OnStatusUpdate("TCP客户端已连接");
} else {
pStatus->OnStatusUpdate("TCP客户端已断开");
}
// 更新机械臂连接状态
pStatus->OnRobotConnectionChanged(connected);
}
// 更新工作状态
CheckAndUpdateWorkStatus();
}
// TCP检测触发回调
bool StatorWorkpiecePositionPresenter::OnTCPDetectionTrigger(bool startWork, int cameraIndex, qint64 timestamp)
{
LOG_DEBUG("TCP detection trigger: startWork=%s, cameraIndex=%d, timestamp=%lld\n",
startWork ? "true" : "false", cameraIndex, timestamp);
// 通知UI接收到TCP扫描请求
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("【TCP协议】接收到工件检测请求");
}
if (!startWork) {
LOG_WARNING("Received stop work signal, ignoring\n");
return false;
}
// 检查相机连接状态
if (!m_bCameraConnected) {
LOG_ERROR("Camera not connected, cannot start detection\n");
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("【TCP协议】相机未连接无法启动检测");
}
return false;
}
m_pendingDetectionTask.store(DETECTION_TASK_WORKPIECE);
// 启动检测
int result = StartDetection(cameraIndex, false); // false表示手动触发
bool success = (result == 0);
if (success) {
LOG_DEBUG("Detection started successfully via TCP trigger\n");
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("开始执行扫描检测...");
}
} else {
LOG_ERROR("Failed to start detection via TCP trigger, error code: %d\n", result);
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("检测启动失败");
}
}
return success;
}
bool StatorWorkpiecePositionPresenter::OnTCPBinDetectionTrigger(int cameraIndex, qint64 timestamp)
{
LOG_DEBUG("TCP bin detection trigger: cameraIndex=%d, timestamp=%lld\n", cameraIndex, timestamp);
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("【TCP协议】接收到料框检测请求");
}
if (!m_bCameraConnected) {
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("【TCP协议】相机未连接无法启动料框检测");
}
return false;
}
m_pendingDetectionTask.store(DETECTION_TASK_BIN);
const int result = StartDetection(cameraIndex, false);
if (result != SUCCESS) {
m_pendingDetectionTask.store(DETECTION_TASK_WORKPIECE);
}
return result == SUCCESS;
}
// 发送检测结果给TCP客户端
void StatorWorkpiecePositionPresenter::_SendDetectionResultToTCP(const StatorWorkpiecePositionDetectionResult& detectionResult, int cameraIndex)
{
if (!m_pTCPServer || !m_bTCPConnected.load()) {
LOG_DEBUG("TCP server not available, skipping result transmission\n");
return;
}
LOG_DEBUG("Sending detection result to TCP clients, camera index: %d\n", cameraIndex);
QStringList fields;
if (detectionResult.errorCode != SUCCESS || detectionResult.positions.empty()) {
fields << "0";
} else {
int poseOutputOrder = POSE_ORDER_RPY;
if (m_pConfigManager) {
poseOutputOrder = m_pConfigManager->GetConfigResult().plcRobotServerConfig.poseOutputOrder;
}
fields << IntField(static_cast<int>(detectionResult.positions.size()));
for (const WorkpiecePosition& position : detectionResult.positions) {
fields << IntField(position.workpieceType)
<< NumberField(position.x)
<< NumberField(position.y)
<< NumberField(position.z);
AppendPoseFields(fields, position, poseOutputOrder);
}
}
const int sendResult = m_pTCPServer->SendTextFrame(fields.join(QStringLiteral("_")).toUtf8());
if (sendResult == 0) {
LOG_INFO("Detection result sent to TCP clients successfully\n");
if (auto pStatus = GetStatusCallback<IYStatorWorkpiecePositionStatus>()) {
pStatus->OnStatusUpdate("【TCP协议】已发送工件检测结果");
}
} else {
LOG_ERROR("Failed to send detection result to TCP clients, error code: %d\n", sendResult);
}
}
void StatorWorkpiecePositionPresenter::_SendBinInfoToTCP(const WD_HRM_BinInfo& binInfo, int cameraIndex, int errorCode)
{
(void)binInfo;
(void)cameraIndex;
(void)errorCode;
LOG_DEBUG("Bin detection has no TCP result frame\n");
}
void StatorWorkpiecePositionPresenter::_SendDetectionErrorToTCP(int errorCode, int cameraIndex)
{
if (!m_pTCPServer || !m_bTCPConnected.load()) {
LOG_DEBUG("TCP server not available, skipping detection error transmission\n");
return;
}
(void)cameraIndex;
const QString frame = QString("Error_%1_检测失败").arg(errorCode);
const int sendResult = m_pTCPServer->SendTextFrame(frame.toUtf8());
if (sendResult != 0) {
LOG_ERROR("Failed to send detection error to TCP clients, error code: %d\n", sendResult);
}
}