GrabBag/App/DroneScrewbolt/DroneScrewServer/DroneScrewZmqProtocol.h
2026-06-26 17:55:15 +08:00

150 lines
4.9 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.

#ifndef DRONESCREW_ZMQ_PROTOCOL_H
#define DRONESCREW_ZMQ_PROTOCOL_H
#include <QObject>
#include <QString>
#include <QByteArray>
#include <QJsonObject>
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include "IVrZeroMQServer.h"
#include "IVrZeroMQPubSub.h"
#include "Algo/IDroneScrewAlgo.h"
#include "IMvsDevice.h"
class QUdpSocket;
/**
* @brief 板一 ZMQ 协议层
*
* - REP socket接收板二的同步控制指令启停、单次检测、参数调整、获取信息
* - PUB socket异步发布检测结果板二订阅显示
*
* 协议消息使用 JSON 编码(可在后续替换为 Protobuf
*
* 控制指令格式:
* { "cmd": "start" }
* { "cmd": "stop" }
* { "cmd": "single" }
* { "cmd": "set_exposure", "value": 10000 }
* { "cmd": "set_gain", "value": 1.0 }
* { "cmd": "set_algo_params", "score": 0.5, "nms": 0.45, "width": 640, "height": 640 }
* { "cmd": "swap_cameras" }
* { "cmd": "get_info" }
*
* 应答统一格式:
* { "ok": true, "code": 0, "msg": "", ... }
*
* 结果发布主题:
* topic: "result"
* payload: { "frameId": .., "ts": .., "boxes": [ {cls,score,x,y,w,h}, ... ] }
*/
class DroneScrewZmqProtocol : public QObject
{
Q_OBJECT
public:
explicit DroneScrewZmqProtocol(QObject* parent = nullptr);
~DroneScrewZmqProtocol() override;
/**
* @brief 启动 ZMQ 协议层
* @param controlPort REQ-REP 控制端口
* @param resultPort PUB 检测结果端口 (topic="result")
* @param rawImagePort PUB 原始图像端口 (topic="raw")<=0 表示不启用
*/
bool startServer(int controlPort, int resultPort, int rawImagePort);
void stopServer();
void setRtspUrl(const QString& url) { m_rtspUrl = url; }
void setSingleDetectionHandler(std::function<DroneScrewResult()> handler)
{
m_singleDetectionHandler = std::move(handler);
}
void setStartWorkHandler(std::function<int()> handler)
{
m_startWorkHandler = std::move(handler);
}
void setStopWorkHandler(std::function<int()> handler)
{
m_stopWorkHandler = std::move(handler);
}
void setStartLiveStreamHandler(std::function<int()> handler)
{
m_startLiveStreamHandler = std::move(handler);
}
void setStopLiveStreamHandler(std::function<int()> handler)
{
m_stopLiveStreamHandler = std::move(handler);
}
void setSwapCameraRolesHandler(std::function<int()> handler)
{
m_swapCameraRolesHandler = std::move(handler);
}
void setServerInfoProvider(std::function<QJsonObject()> provider)
{
m_serverInfoProvider = std::move(provider);
}
void setCalibrationInfoProvider(std::function<QJsonObject()> provider)
{
m_calibrationInfoProvider = std::move(provider);
}
int controlPort() const { return m_controlPort; }
int resultPort() const { return m_resultPort; }
int rawImagePort() const { return m_rawImagePort; }
signals:
void rawImagePublishEnabledRequested(bool enabled);
void detectModeRequested(const std::string& mode);
void setExposureRequested(double exposureTime);
void setGainRequested(double gain);
void updateAlgoParamsRequested(const DroneScrewAlgoParams& params);
public slots:
/**
* @brief 接收 presenter 信号,封装为 ZMQ 发布topic="result"
*/
void publishDetectionResult(const DroneScrewResult& result);
/**
* @brief 接收 presenter 采集到的双目原始相机帧并以 ZMQ PUBtopic="raw")广播
*
* payload = WDRemoteBinocularRawImageHeader(88B) + left raw bytes + right raw bytes
*/
void publishRawImage(const MvsImageData& left, const MvsImageData& right);
private:
QByteArray handleControlMessage(const QByteArray& reqData);
bool startDiscoveryServer();
void stopDiscoveryServer();
void handleDiscoveryDatagrams();
private:
IVrZeroMQServer* m_pZmqServer{nullptr};
IVrZeroMQPublisher* m_pZmqPublisher{nullptr}; // topic="result"
IVrZeroMQPublisher* m_pZmqRawPublisher{nullptr}; // topic="raw"
QUdpSocket* m_pDiscoverySocket{nullptr}; // UDP broadcast discovery
std::atomic<bool> m_bRunning{false};
QString m_rtspUrl;
int m_controlPort{0};
int m_resultPort{0};
int m_rawImagePort{0};
std::mutex m_pubMutex;
std::mutex m_rawMutex;
std::mutex m_singleMutex;
std::function<DroneScrewResult()> m_singleDetectionHandler;
std::function<int()> m_startWorkHandler;
std::function<int()> m_stopWorkHandler;
std::function<int()> m_startLiveStreamHandler;
std::function<int()> m_stopLiveStreamHandler;
std::function<int()> m_swapCameraRolesHandler;
std::function<QJsonObject()> m_serverInfoProvider;
std::function<QJsonObject()> m_calibrationInfoProvider;
};
#endif // DRONESCREW_ZMQ_PROTOCOL_H