2025-12-20 16:18:12 +08:00

173 lines
8.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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

#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <iostream>
#include "BinocularMarkPresenter.h"
#include "BinocularMarkTcpProtocol.h"
#include "PathManager.h"
#include "Version.h"
#include "VrLog.h"
#include "IVrUtils.h"
#include "binocularMarkCam_Export.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 设置应用程序信息
app.setApplicationName(BINOCULAR_MARK_PRODUCT_NAME);
app.setApplicationVersion(BINOCULAR_MARK_VERSION_STRING);
app.setOrganizationName(BINOCULAR_MARK_COMPANY_NAME);
// 初始化日志
VrLogUtils::InitLog();
VrLogUtils::EnableTime(false);
// 打印启动横幅
LOG_DEBUG("===========================================\n");
LOG_INFO(" %s\n", BINOCULAR_MARK_PRODUCT_NAME);
LOG_INFO(" %s\n", BINOCULAR_MARK_VERSION_STRING);
LOG_INFO(" %s\n", BINOCULAR_MARK_VERSION_BUILD);
LOG_DEBUG("===========================================\n");
// 打印算法版本
const char* algoVersion = wd_charuco3DMarkVersion();
LOG_INFO("Algorithm Version: %s\n", algoVersion);
// 注册自定义类型用于信号槽
qRegisterMetaType<std::vector<SWD_charuco3DMark>>("std::vector<SWD_charuco3DMark>");
qRegisterMetaType<cv::Mat>("cv::Mat");
// 创建Presenter和TCP协议处理对象
BinocularMarkPresenter presenter;
BinocularMarkTcpProtocol tcpProtocol;
// 连接信号槽
QObject::connect(&presenter, &BinocularMarkPresenter::detectionResult, &tcpProtocol, &BinocularMarkTcpProtocol::sendMarkResult);
QObject::connect(&presenter, &BinocularMarkPresenter::singleDetectionResult, &tcpProtocol, &BinocularMarkTcpProtocol::sendSingleDetectionResult);
QObject::connect(&presenter, &BinocularMarkPresenter::singleImageResult, &tcpProtocol, &BinocularMarkTcpProtocol::sendImageData);
QObject::connect(&presenter, &BinocularMarkPresenter::cameraInfoResult, &tcpProtocol, &BinocularMarkTcpProtocol::sendCameraInfoResponse);
QObject::connect(&presenter, &BinocularMarkPresenter::calibrationMatrixResult, &tcpProtocol, &BinocularMarkTcpProtocol::sendCalibrationMatrixResponse);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::singleDetectionRequested, &presenter, &BinocularMarkPresenter::handleSingleDetection);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::singleImageRequested, &presenter, &BinocularMarkPresenter::handleSingleImage);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::startWorkRequested, &presenter, &BinocularMarkPresenter::handleStartWork);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::stopWorkRequested, &presenter, &BinocularMarkPresenter::handleStopWork);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::startContinuousImageRequested, &presenter, &BinocularMarkPresenter::handleStartContinuousImage);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::stopContinuousImageRequested, &presenter, &BinocularMarkPresenter::handleStopContinuousImage);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setExposureTimeRequested, &presenter, &BinocularMarkPresenter::handleSetExposureTime);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setGainRequested, &presenter, &BinocularMarkPresenter::handleSetGain);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setLeftExposureTimeRequested, &presenter, &BinocularMarkPresenter::handleSetLeftExposureTime);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setRightExposureTimeRequested, &presenter, &BinocularMarkPresenter::handleSetRightExposureTime);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setLeftGainRequested, &presenter, &BinocularMarkPresenter::handleSetLeftGain);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setRightGainRequested, &presenter, &BinocularMarkPresenter::handleSetRightGain);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::getCameraInfoRequested, &presenter, &BinocularMarkPresenter::handleGetCameraInfo);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::getCalibrationRequested, &presenter, &BinocularMarkPresenter::handleGetCalibration);
QObject::connect(&tcpProtocol, &BinocularMarkTcpProtocol::setCalibrationRequested, &presenter, &BinocularMarkPresenter::handleSetCalibration);
// 获取配置文件路径(通过 PathManager 自动判断加密或明文)
QString configFilePath = PathManager::GetInstance().GetConfigFilePath();
// 加载配置文件
if (!presenter.loadConfiguration(configFilePath))
{
LOG_WARN("Warning: Failed to load configuration file. Using default settings.\n");
LOG_INFO("Config file location: %s\n", configFilePath.toStdString().c_str());
}
// 启动TCP服务器
quint16 serverPort = presenter.getServerPort();
if (serverPort == 0)
{
serverPort = 5901; // 默认端口
}
if (!tcpProtocol.startServer(serverPort))
{
LOG_ERROR("Failed to start TCP server on port %d\n", serverPort);
return -1;
}
// 不需要向外的心跳,客户端会发送心跳
// tcpProtocol.startHeartbeat(30);
// 初始化双目相机不启动采集线程等待cmd_start_work命令
int cameraResult = presenter.initCameras();
if (cameraResult != 0)
{
LOG_WARN("Failed to initialize cameras, will retry on client request\n");
}
// 设置版本信息文本:版本号 + 编译时间
QString versionText = QString("%1_%2_%3")
.arg(BINOCULAR_MARK_VERSION_STRING)
.arg(BINOCULAR_MARK_VERSION_BUILD)
.arg(BUILD_TIME.c_str());
// 输出系统信息
LOG_INFO("=== BinocularMark Server Started %s ===\n", versionText.toStdString().c_str());
LOG_INFO("Server is running on port %d\n", serverPort);
LOG_INFO("Press Ctrl+C to exit.\n");
#if 0 // 将 0 改为 1 可启用模拟线程
#ifdef _WIN32
LOG_INFO("Simulation thread started - sending test data every 5 seconds\n");
// 模拟线程:定期发送模拟的 Mark 检测结果
std::thread testThread([&presenter]() {
QThread::sleep(5); // 等待5秒确保系统启动完成
int frameCounter = 0;
while (true)
{
// 生成模拟的 Mark 数据
std::vector<SWD_charuco3DMark> simulatedMarks;
// 模拟检测到 4 个 Mark
for (int i = 0; i < 4; i++)
{
SWD_charuco3DMark mark;
mark.mark3D.markID = i;
// 模拟位置:在 (100, 200, 300) 附近随机分布
mark.mark3D.x = 100.0 + (rand() % 100 - 50) / 10.0; // 95.0 ~ 105.0
mark.mark3D.y = 200.0 + (rand() % 100 - 50) / 10.0; // 195.0 ~ 205.0
mark.mark3D.z = 300.0 + (rand() % 100 - 50) / 10.0; // 295.0 ~ 305.0
simulatedMarks.push_back(mark);
}
// 生成模拟图像640x480 灰度图)
cv::Mat simulatedLeftImage(480, 640, CV_8UC1, cv::Scalar(128));
cv::Mat simulatedRightImage(480, 640, CV_8UC1, cv::Scalar(120));
// 在图像上绘制一些标记
for (size_t i = 0; i < simulatedMarks.size(); i++)
{
cv::Point center(100 + i * 150, 240);
cv::circle(simulatedLeftImage, center, 20, cv::Scalar(255), 2);
cv::putText(simulatedLeftImage, std::to_string(i),
cv::Point(center.x - 10, center.y + 5),
cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255), 2);
}
// 发送模拟数据(通过信号)
emit presenter.detectionResult(simulatedMarks, simulatedLeftImage, simulatedRightImage, SUCCESS);
frameCounter++;
LOG_DEBUG("Simulation: Sent frame #%d with %zu marks\n", frameCounter, simulatedMarks.size());
// 等待5秒
QThread::sleep(5);
}
});
testThread.detach();
#endif
#endif
return app.exec();
}