155 lines
5.1 KiB
C++
155 lines
5.1 KiB
C++
#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 setFinalDetectionResultProvider(std::function<bool(DroneScrewResult&)> provider)
|
||
{
|
||
m_finalDetectionResultProvider = std::move(provider);
|
||
}
|
||
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 PUB(topic="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<bool(DroneScrewResult&)> m_finalDetectionResultProvider;
|
||
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
|