GrabBag/Module/BinocularMarkReceiver/Src/BinocularMarkReceiver.cpp

826 lines
28 KiB
C++
Raw Normal View History

2025-12-10 00:01:32 +08:00
#include "BinocularMarkReceiver.h"
#include "json/json.h"
#include "VrLog.h"
#include <algorithm>
#include <chrono>
#include <cstring>
using namespace VA;
2025-12-10 00:01:32 +08:00
// 静态工厂方法实现
int IBinocularMarkReceiver::CreateInstance(IBinocularMarkReceiver** ppReceiver)
{
if (!ppReceiver) {
return -1;
}
*ppReceiver = new BinocularMarkReceiver();
return 0;
}
BinocularMarkReceiver::BinocularMarkReceiver()
: m_pTcpClient(nullptr)
2025-12-10 00:01:32 +08:00
, m_serverPort(0)
, m_bConnected(false)
, m_bSingleDetectionReady(false)
, m_bImageDataReady(false)
2025-12-20 16:18:12 +08:00
, m_bLeftCameraInfoReady(false)
, m_bRightCameraInfoReady(false)
, m_bCalibrationMatrixReady(false)
, m_bHeartbeatRunning(false)
2025-12-20 16:18:12 +08:00
, m_bHeartbeatEnabled(false)
, m_nHeartbeatInterval(30)
2025-12-10 00:01:32 +08:00
{
m_pTcpClient = IVrTCPClient::CreateInstance();
2025-12-10 00:01:32 +08:00
}
BinocularMarkReceiver::~BinocularMarkReceiver()
{
Disconnect();
if (m_pTcpClient) {
IVrTCPClient::DestroyInstance(m_pTcpClient);
m_pTcpClient = nullptr;
}
2025-12-10 00:01:32 +08:00
}
int BinocularMarkReceiver::Connect(const std::string& serverIp, uint16_t serverPort)
2025-12-10 00:01:32 +08:00
{
if (m_bConnected) {
LOG_DEBUG("Already connected\n");
2025-12-10 00:01:32 +08:00
return 0;
}
m_serverIp = serverIp;
m_serverPort = serverPort;
LOG_DEBUG("Connecting to %s:%d\n", serverIp.c_str(), serverPort);
2025-12-10 00:01:32 +08:00
// 连接到服务器
int ret = m_pTcpClient->LinkDevice(serverIp, serverPort, false, linkEventCallback, this);
if (ret != 0) {
LOG_DEBUG("LinkDevice failed: %d\n", ret);
return -1;
}
2025-12-10 00:01:32 +08:00
// 启动工作线程
ret = m_pTcpClient->StartWork(tcpRecvCallback, this);
if (ret != 0) {
LOG_DEBUG("StartWork failed: %d\n", ret);
m_pTcpClient->CloseDevice();
2025-12-10 00:01:32 +08:00
return -1;
}
LOG_DEBUG("Connect initiated\n");
2025-12-10 00:01:32 +08:00
return 0;
}
int BinocularMarkReceiver::Disconnect()
{
if (!m_bConnected) {
return 0;
}
// 停止心跳线程
m_bHeartbeatRunning = false;
2025-12-20 16:18:12 +08:00
m_cvHeartbeat.notify_one(); // 唤醒心跳线程
if (m_heartbeatThread.joinable()) {
m_heartbeatThread.join();
}
2025-12-10 00:01:32 +08:00
// 断开连接
if (m_pTcpClient) {
m_pTcpClient->CloseDevice();
2025-12-10 00:01:32 +08:00
}
m_bConnected = false;
m_dataBuffer.clear();
2025-12-20 16:18:12 +08:00
// 通知所有等待的条件变量,避免其他线程卡住
m_cvSingleDetection.notify_all();
m_cvImageData.notify_all();
m_cvLeftCameraInfo.notify_all();
m_cvRightCameraInfo.notify_all();
m_cvCalibrationMatrix.notify_all();
2025-12-10 00:01:32 +08:00
return 0;
}
bool BinocularMarkReceiver::IsConnected() const
{
return m_bConnected;
}
2025-12-20 16:18:12 +08:00
void BinocularMarkReceiver::SetMarkResultCallback(MarkResultCallback callback)
2025-12-10 00:01:32 +08:00
{
2025-12-20 16:18:12 +08:00
std::lock_guard<std::mutex> lock(m_mutex);
m_markResultCallback = callback;
2025-12-10 00:01:32 +08:00
}
2025-12-20 16:18:12 +08:00
void BinocularMarkReceiver::SetImageCallback(ImageCallback callback)
2025-12-10 00:01:32 +08:00
{
std::lock_guard<std::mutex> lock(m_mutex);
2025-12-20 16:18:12 +08:00
m_imageCallback = callback;
2025-12-10 00:01:32 +08:00
}
void BinocularMarkReceiver::SetEventCallback(EventCallback callback)
2025-12-10 00:01:32 +08:00
{
std::lock_guard<std::mutex> lock(m_mutex);
m_eventCallback = callback;
2025-12-10 00:01:32 +08:00
}
// TCP连接状态回调
void BinocularMarkReceiver::linkEventCallback(IVrTCPClient* pClient, bool connected, void* pParam)
2025-12-10 00:01:32 +08:00
{
BinocularMarkReceiver* pThis = static_cast<BinocularMarkReceiver*>(pParam);
if (!pThis) return;
2025-12-10 00:01:32 +08:00
pThis->m_bConnected = connected;
2025-12-10 00:01:32 +08:00
2025-12-20 16:18:12 +08:00
// 获取回调函数的拷贝,在锁外调用
EventCallback callback;
{
std::lock_guard<std::mutex> lock(pThis->m_mutex);
callback = pThis->m_eventCallback;
}
if (connected) {
LOG_DEBUG("Connected to server\n");
2025-12-20 16:18:12 +08:00
// 在锁外触发连接事件
if (callback) {
callback(ReceiverEventType::CONNECTED, "");
}
2025-12-10 00:01:32 +08:00
// 启动心跳线程
pThis->m_bHeartbeatRunning = true;
pThis->m_heartbeatThread = std::thread(&BinocularMarkReceiver::heartbeatThreadFunc, pThis);
} else {
LOG_DEBUG("Disconnected from server\n");
2025-12-20 16:18:12 +08:00
// 在锁外触发断开连接事件
if (callback) {
callback(ReceiverEventType::DISCONNECTED, "");
}
2025-12-10 00:01:32 +08:00
}
}
// TCP数据接收回调
void BinocularMarkReceiver::tcpRecvCallback(IVrTCPClient* pClient, const char* pData, const int nLen, void* pParam)
2025-12-10 00:01:32 +08:00
{
BinocularMarkReceiver* pThis = static_cast<BinocularMarkReceiver*>(pParam);
if (!pThis || !pData || nLen <= 0) return;
2025-12-10 00:01:32 +08:00
// 追加到缓冲区
2025-12-10 00:01:32 +08:00
{
std::lock_guard<std::mutex> lock(pThis->m_mutex);
pThis->m_dataBuffer.insert(pThis->m_dataBuffer.end(), pData, pData + nLen);
2025-12-10 00:01:32 +08:00
}
// 解析数据帧
pThis->parseFrames();
2025-12-10 00:01:32 +08:00
}
// 心跳线程函数
void BinocularMarkReceiver::heartbeatThreadFunc()
2025-12-10 00:01:32 +08:00
{
while (m_bHeartbeatRunning) {
2025-12-20 16:18:12 +08:00
// 使用 condition_variable 实现可中断的等待
std::unique_lock<std::mutex> lock(m_mutexHeartbeat);
m_cvHeartbeat.wait_for(lock, std::chrono::seconds(m_nHeartbeatInterval),
[this] { return !m_bHeartbeatRunning; });
2025-12-10 00:01:32 +08:00
if (!m_bHeartbeatRunning) break;
2025-12-10 00:01:32 +08:00
2025-12-20 16:18:12 +08:00
// 检查是否启用心跳
if (!m_bHeartbeatEnabled) continue;
// 发送心跳消息
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
2025-12-10 00:01:32 +08:00
Json::FastWriter writer;
std::string jsonData = writer.write(root);
2025-12-10 00:01:32 +08:00
sendJsonMessage("heartbeat", jsonData);
}
2025-12-10 00:01:32 +08:00
}
void BinocularMarkReceiver::parseFrames()
2025-12-10 00:01:32 +08:00
{
2025-12-20 16:18:12 +08:00
std::vector<std::string> messagesToProcess;
2025-12-20 16:18:12 +08:00
{
std::lock_guard<std::mutex> lock(m_mutex);
while (true) {
// 查找帧头
auto it = std::search(m_dataBuffer.begin(), m_dataBuffer.end(), FRAME_HEADER, FRAME_HEADER + FRAME_HEADER_SIZE);
if (it == m_dataBuffer.end()) {
m_dataBuffer.clear();
break;
}
// 丢弃帧头之前的数据
if (it != m_dataBuffer.begin()) {
m_dataBuffer.erase(m_dataBuffer.begin(), it);
}
// 检查是否有足够的数据来读取长度字段
if (m_dataBuffer.size() < FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE) {
break;
}
// 读取数据长度8字节ASCII字符串格式
std::string lengthStr(m_dataBuffer.begin() + FRAME_HEADER_SIZE, m_dataBuffer.begin() + FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE);
int64_t dataLength = std::stoll(lengthStr);
// 检查数据长度是否合理最大50MB支持双目高分辨率图像
if (dataLength < 0 || dataLength > 50 * 1024 * 1024) {
LOG_WARN("Invalid data length: %lld, discarding frame header\n", dataLength);
m_dataBuffer.erase(m_dataBuffer.begin(), m_dataBuffer.begin() + FRAME_HEADER_SIZE);
continue;
}
// 计算完整帧的总长度
size_t totalFrameLength = FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE + dataLength + FRAME_TAIL_SIZE;
// 检查是否有完整的帧
if (m_dataBuffer.size() < totalFrameLength) {
break;
}
// 提取JSON数据
std::string jsonData(m_dataBuffer.begin() + FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE,
m_dataBuffer.begin() + FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE + dataLength);
// 验证帧尾
std::string tail(m_dataBuffer.begin() + FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE + dataLength,
m_dataBuffer.begin() + FRAME_HEADER_SIZE + FRAME_LENGTH_SIZE + dataLength + FRAME_TAIL_SIZE);
if (tail != FRAME_TAIL) {
m_dataBuffer.erase(m_dataBuffer.begin(), m_dataBuffer.begin() + FRAME_HEADER_SIZE);
continue;
}
// 收集消息,稍后在锁外处理
messagesToProcess.push_back(jsonData);
// 移除已处理的帧
m_dataBuffer.erase(m_dataBuffer.begin(), m_dataBuffer.begin() + totalFrameLength);
2025-12-10 00:01:32 +08:00
}
2025-12-20 16:18:12 +08:00
} // 释放锁
2025-12-10 00:01:32 +08:00
2025-12-20 16:18:12 +08:00
// 在锁外处理所有消息
for (const auto& jsonData : messagesToProcess) {
2025-12-10 00:01:32 +08:00
handleJsonMessage(jsonData);
}
}
void BinocularMarkReceiver::handleJsonMessage(const std::string& jsonData)
2025-12-10 00:01:32 +08:00
{
Json::Reader reader;
Json::Value root;
2025-12-10 00:01:32 +08:00
if (!reader.parse(jsonData, root)) {
LOG_DEBUG("JSON parse failed\n");
2025-12-10 00:01:32 +08:00
return;
}
if (!root.isObject()) {
LOG_DEBUG("JSON is not an object\n");
2025-12-10 00:01:32 +08:00
return;
}
// 获取消息类型
std::string messageType = root.get("msg_type", "").asString();
LOG_DEBUG("Received message type: %s\n", messageType.c_str());
if (messageType == "mark_result") {
handleMarkResult(jsonData);
} else if (messageType == "single_detection_result") {
handleSingleDetectionResult(jsonData);
} else if (messageType == "image_data") {
handleImageData(jsonData);
2025-12-20 16:18:12 +08:00
} else if (messageType == "heartbeat") {
handleHeartbeat(jsonData);
} else if (messageType == "heartbeat_ack") {
handleHeartbeatAck(jsonData);
} else if (messageType == "cmd_response") {
handleCommandResponse(jsonData);
2025-12-20 16:18:12 +08:00
} else if (messageType == "camera_info_response") {
handleCameraInfoResponse(jsonData);
} else if (messageType == "calibration_matrix_response") {
handleCalibrationMatrixResponse(jsonData);
2025-12-10 00:01:32 +08:00
} else {
LOG_DEBUG("Unknown message type: %s\n", messageType.c_str());
2025-12-10 00:01:32 +08:00
}
}
void BinocularMarkReceiver::handleMarkResult(const std::string& jsonStr)
2025-12-10 00:01:32 +08:00
{
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonStr, root)) return;
2025-12-10 00:01:32 +08:00
int64_t timestamp = root.get("timestamp", 0).asInt64();
int errorCode = root.get("error_code", -1).asInt();
2025-12-10 00:01:32 +08:00
std::vector<VrMark3D> marks;
if (errorCode == 0 && root.isMember("marks")) {
const Json::Value& marksArray = root["marks"];
for (unsigned int i = 0; i < marksArray.size(); i++) {
2025-12-10 00:01:32 +08:00
VrMark3D mark;
mark.markID = marksArray[i].get("mark_id", -1).asInt();
mark.x = marksArray[i].get("x", 0.0).asDouble();
mark.y = marksArray[i].get("y", 0.0).asDouble();
mark.z = marksArray[i].get("z", 0.0).asDouble();
2025-12-10 00:01:32 +08:00
marks.push_back(mark);
}
}
2025-12-20 16:18:12 +08:00
// 提取图像数据
std::string leftImageBase64 = root.get("left_image", "").asString();
std::string rightImageBase64 = root.get("right_image", "").asString();
// 如果有图像数据且注册了图像回调,触发图像回调
if (!leftImageBase64.empty() && !rightImageBase64.empty()) {
ImageCallback imageCallback;
{
std::lock_guard<std::mutex> lock(m_mutex);
imageCallback = m_imageCallback;
}
if (imageCallback) {
imageCallback(leftImageBase64, rightImageBase64, timestamp);
}
}
// 如果有marks数据且注册了mark回调触发mark回调
if (!marks.empty()) {
MarkResultCallback callback;
{
std::lock_guard<std::mutex> lock(m_mutex);
callback = m_markResultCallback;
}
if (callback) {
callback(marks, timestamp, errorCode);
}
2025-12-10 00:01:32 +08:00
}
}
2025-12-20 16:18:12 +08:00
void BinocularMarkReceiver::handleHeartbeat(const std::string& jsonStr)
{
// 收到服务器心跳,回复心跳应答
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
sendJsonMessage("heartbeat_ack", jsonData);
}
void BinocularMarkReceiver::handleHeartbeatAck(const std::string& jsonStr)
2025-12-10 00:01:32 +08:00
{
// 心跳应答,暂时不处理
}
void BinocularMarkReceiver::handleCommandResponse(const std::string& jsonStr)
2025-12-10 00:01:32 +08:00
{
// 命令应答,暂时不处理
2025-12-10 00:01:32 +08:00
}
std::string BinocularMarkReceiver::buildFrame(const std::string& jsonData)
2025-12-10 00:01:32 +08:00
{
std::string frame;
2025-12-10 00:01:32 +08:00
// 添加帧头
frame.append(FRAME_HEADER, FRAME_HEADER_SIZE);
// 添加数据长度8字节ASCII字符串格式
char lengthStr[9];
snprintf(lengthStr, sizeof(lengthStr), "%08zu", jsonData.size());
2025-12-10 00:01:32 +08:00
frame.append(lengthStr, FRAME_LENGTH_SIZE);
// 添加JSON数据
frame.append(jsonData);
// 添加帧尾
frame.append(FRAME_TAIL, FRAME_TAIL_SIZE);
return frame;
}
int BinocularMarkReceiver::sendJsonMessage(const std::string& messageType, const std::string& jsonData)
2025-12-10 00:01:32 +08:00
{
if (!m_bConnected) {
return -1;
}
// 解析JSON并添加msg_type字段
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonData, root)) {
root = Json::Value(Json::objectValue);
}
root["msg_type"] = messageType;
2025-12-10 00:01:32 +08:00
// 转换为JSON字符串
Json::FastWriter writer;
std::string finalJsonData = writer.write(root);
2025-12-10 00:01:32 +08:00
// 构造数据帧
std::string frame = buildFrame(finalJsonData);
2025-12-10 00:01:32 +08:00
// 发送数据
if (!m_pTcpClient->SendData(frame.c_str(), frame.size())) {
2025-12-10 00:01:32 +08:00
return -1;
}
return 0;
}
// ========== 新增接口实现 ==========
IBinocularMarkReceiver::SingleDetectionResult BinocularMarkReceiver::RequestSingleDetection(int timeoutMs)
{
SingleDetectionResult result;
result.errorCode = -1;
if (!m_bConnected) {
return result;
}
// 发送请求
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
m_bSingleDetectionReady = false;
if (sendJsonMessage("cmd_single_detection", jsonData) != 0) {
return result;
}
// 使用condition_variable同步等待结果
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cvSingleDetection.wait_for(lock, std::chrono::milliseconds(timeoutMs),
[this] { return m_bSingleDetectionReady; })) {
return m_pendingSingleDetectionResult;
}
result.errorCode = -2; // 超时
return result;
}
IBinocularMarkReceiver::ImageData BinocularMarkReceiver::RequestSingleImage(int timeoutMs)
{
ImageData result;
result.timestamp = 0;
if (!m_bConnected) {
return result;
}
// 发送请求
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
m_bImageDataReady = false;
if (sendJsonMessage("cmd_single_image", jsonData) != 0) {
return result;
}
// 使用condition_variable同步等待结果
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cvImageData.wait_for(lock, std::chrono::milliseconds(timeoutMs), [this] { return m_bImageDataReady; })) {
return m_pendingImageData;
}
return result;
}
int BinocularMarkReceiver::StartWork()
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_start_work", jsonData);
}
int BinocularMarkReceiver::StopWork()
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_stop_work", jsonData);
}
2025-12-20 16:18:12 +08:00
int BinocularMarkReceiver::StartCapture()
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_start_continuous_image", jsonData);
}
int BinocularMarkReceiver::StopCapture()
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_stop_continuous_image", jsonData);
}
int BinocularMarkReceiver::SetCalibrationMatrix(const std::string& calibrationXml)
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
root["calibration_xml"] = calibrationXml;
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_set_calibration", jsonData);
}
2025-12-20 16:18:12 +08:00
int BinocularMarkReceiver::SetExposureTime(SVrCameraEnum target, double exposureTime)
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
root["exposure_time"] = exposureTime;
2025-12-20 16:18:12 +08:00
if (target == SVrCameraEnum::LEFT) {
root["camera"] = "left";
} else if (target == SVrCameraEnum::RIGHT) {
root["camera"] = "right";
}
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_set_exposure_time", jsonData);
}
2025-12-20 16:18:12 +08:00
int BinocularMarkReceiver::SetGain(SVrCameraEnum target, double gain)
{
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
root["gain"] = gain;
2025-12-20 16:18:12 +08:00
if (target == SVrCameraEnum::LEFT) {
root["camera"] = "left";
} else if (target == SVrCameraEnum::RIGHT) {
root["camera"] = "right";
}
Json::FastWriter writer;
std::string jsonData = writer.write(root);
return sendJsonMessage("cmd_set_gain", jsonData);
}
2025-12-20 16:18:12 +08:00
IBinocularMarkReceiver::CameraInfo BinocularMarkReceiver::GetCameraInfo(SVrCameraEnum target, int timeoutMs)
{
CameraInfo result;
result.exposureTime = 0.0;
result.gain = 0.0;
if (!m_bConnected || target == SVrCameraEnum::BOTH) {
return result;
}
// 发送请求
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
root["camera"] = (target == SVrCameraEnum::LEFT) ? "left" : "right";
Json::FastWriter writer;
std::string jsonData = writer.write(root);
if (target == SVrCameraEnum::LEFT) {
m_bLeftCameraInfoReady = false;
if (sendJsonMessage("cmd_get_camera_info", jsonData) != 0) {
return result;
}
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cvLeftCameraInfo.wait_for(lock, std::chrono::milliseconds(timeoutMs),
[this] { return m_bLeftCameraInfoReady; })) {
return m_pendingLeftCameraInfo;
}
} else {
m_bRightCameraInfoReady = false;
if (sendJsonMessage("cmd_get_camera_info", jsonData) != 0) {
return result;
}
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cvRightCameraInfo.wait_for(lock, std::chrono::milliseconds(timeoutMs),
[this] { return m_bRightCameraInfoReady; })) {
return m_pendingRightCameraInfo;
}
}
return result;
}
std::string BinocularMarkReceiver::GetCalibrationMatrix(int timeoutMs)
{
std::string result;
if (!m_bConnected) {
return result;
}
// 发送请求
Json::Value root;
root["timestamp"] = static_cast<Json::Int64>(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
Json::FastWriter writer;
std::string jsonData = writer.write(root);
m_bCalibrationMatrixReady = false;
if (sendJsonMessage("cmd_get_calibration", jsonData) != 0) {
return result;
}
std::unique_lock<std::mutex> lock(m_mutex);
if (m_cvCalibrationMatrix.wait_for(lock, std::chrono::milliseconds(timeoutMs),
[this] { return m_bCalibrationMatrixReady; })) {
return m_pendingCalibrationMatrix;
}
return result;
}
void BinocularMarkReceiver::handleSingleDetectionResult(const std::string& jsonStr)
{
LOG_DEBUG("handleSingleDetectionResult start, JSON size: %zu\n", jsonStr.size());
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonStr, root)) {
LOG_DEBUG("handleSingleDetectionResult JSON parse failed\n");
return;
}
LOG_DEBUG("handleSingleDetectionResult JSON parsed\n");
int64_t timestamp = root.get("timestamp", 0).asInt64();
int errorCode = root.get("error_code", -1).asInt();
std::string leftImageBase64 = root.get("left_image", "").asString();
std::string rightImageBase64 = root.get("right_image", "").asString();
LOG_DEBUG("handleSingleDetectionResult got data: timestamp=%lld, error=%d, left_size=%zu, right_size=%zu\n",
timestamp, errorCode, leftImageBase64.size(), rightImageBase64.size());
std::vector<VrMark3D> marks;
if (errorCode == 0 && root.isMember("marks")) {
const Json::Value& marksArray = root["marks"];
for (unsigned int i = 0; i < marksArray.size(); i++) {
VrMark3D mark;
mark.markID = marksArray[i].get("mark_id", -1).asInt();
mark.x = marksArray[i].get("x", 0.0).asDouble();
mark.y = marksArray[i].get("y", 0.0).asDouble();
mark.z = marksArray[i].get("z", 0.0).asDouble();
marks.push_back(mark);
}
}
LOG_DEBUG("handleSingleDetectionResult parsed %zu marks\n", marks.size());
// 存储结果并通知等待的线程
{
2025-12-20 16:18:12 +08:00
std::lock_guard<std::mutex> lock(m_mutex);
LOG_DEBUG("handleSingleDetectionResult storing data\n");
m_pendingSingleDetectionResult.marks = marks;
m_pendingSingleDetectionResult.leftImageBase64 = leftImageBase64;
m_pendingSingleDetectionResult.rightImageBase64 = rightImageBase64;
m_pendingSingleDetectionResult.timestamp = timestamp;
m_pendingSingleDetectionResult.errorCode = errorCode;
m_bSingleDetectionReady = true;
LOG_DEBUG("handleSingleDetectionResult data stored\n");
2025-12-20 16:18:12 +08:00
} // 释放锁后再通知
LOG_DEBUG("handleSingleDetectionResult notifying\n");
m_cvSingleDetection.notify_one();
LOG_DEBUG("handleSingleDetectionResult complete\n");
}
void BinocularMarkReceiver::handleImageData(const std::string& jsonStr)
{
LOG_DEBUG("handleImageData start, JSON size: %zu\n", jsonStr.size());
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonStr, root)) {
LOG_DEBUG("handleImageData JSON parse failed\n");
return;
}
LOG_DEBUG("handleImageData JSON parsed\n");
int64_t timestamp = root.get("timestamp", 0).asInt64();
std::string leftImageBase64 = root.get("left_image", "").asString();
std::string rightImageBase64 = root.get("right_image", "").asString();
LOG_DEBUG("handleImageData got data: timestamp=%lld, left_size=%zu, right_size=%zu\n", timestamp, leftImageBase64.size(), rightImageBase64.size());
// 存储结果并通知等待的线程
{
2025-12-20 16:18:12 +08:00
std::lock_guard<std::mutex> lock(m_mutex);
LOG_DEBUG("handleImageData storing data\n");
m_pendingImageData.leftImageBase64 = leftImageBase64;
m_pendingImageData.rightImageBase64 = rightImageBase64;
m_pendingImageData.timestamp = timestamp;
m_bImageDataReady = true;
LOG_DEBUG("handleImageData data stored\n");
2025-12-20 16:18:12 +08:00
} // 释放锁后再通知
LOG_DEBUG("handleImageData notifying\n");
m_cvImageData.notify_one();
LOG_DEBUG("handleImageData complete\n");
}
2025-12-20 16:18:12 +08:00
void BinocularMarkReceiver::handleCameraInfoResponse(const std::string& jsonStr)
{
LOG_DEBUG("handleCameraInfoResponse start, JSON size: %zu\n", jsonStr.size());
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonStr, root)) {
LOG_DEBUG("handleCameraInfoResponse JSON parse failed\n");
return;
}
LOG_DEBUG("handleCameraInfoResponse JSON parsed\n");
std::string camera = root.get("camera", "").asString();
std::string serialNumber = root.get("serial_number", "").asString();
std::string modelName = root.get("model_name", "").asString();
std::string displayName = root.get("display_name", "").asString();
double exposureTime = root.get("exposure_time", 0.0).asDouble();
double gain = root.get("gain", 0.0).asDouble();
LOG_DEBUG("handleCameraInfoResponse got data: camera=%s, SN=%s, model=%s, exposure=%.2f, gain=%.2f\n",
camera.c_str(), serialNumber.c_str(), modelName.c_str(), exposureTime, gain);
// 存储结果并通知等待的线程
{
std::lock_guard<std::mutex> lock(m_mutex);
LOG_DEBUG("handleCameraInfoResponse storing data\n");
if (camera == "left") {
m_pendingLeftCameraInfo.serialNumber = serialNumber;
m_pendingLeftCameraInfo.modelName = modelName;
m_pendingLeftCameraInfo.displayName = displayName;
m_pendingLeftCameraInfo.exposureTime = exposureTime;
m_pendingLeftCameraInfo.gain = gain;
m_bLeftCameraInfoReady = true;
LOG_DEBUG("handleCameraInfoResponse left camera data stored\n");
} else if (camera == "right") {
m_pendingRightCameraInfo.serialNumber = serialNumber;
m_pendingRightCameraInfo.modelName = modelName;
m_pendingRightCameraInfo.displayName = displayName;
m_pendingRightCameraInfo.exposureTime = exposureTime;
m_pendingRightCameraInfo.gain = gain;
m_bRightCameraInfoReady = true;
LOG_DEBUG("handleCameraInfoResponse right camera data stored\n");
}
} // 释放锁后再通知
LOG_DEBUG("handleCameraInfoResponse notifying\n");
if (camera == "left") {
m_cvLeftCameraInfo.notify_one();
} else if (camera == "right") {
m_cvRightCameraInfo.notify_one();
}
LOG_DEBUG("handleCameraInfoResponse complete\n");
}
void BinocularMarkReceiver::handleCalibrationMatrixResponse(const std::string& jsonStr)
{
Json::Reader reader;
Json::Value root;
if (!reader.parse(jsonStr, root)) {
return;
}
std::string calibrationXml = root.get("calibration_xml", "").asString();
{
std::lock_guard<std::mutex> lock(m_mutex);
m_pendingCalibrationMatrix = calibrationXml;
m_bCalibrationMatrixReady = true;
}
m_cvCalibrationMatrix.notify_one();
}