#include "RobotProtocol.h" #include "VrLog.h" #include "VrError.h" #include "IYModbusTCPServer.h" #include #include RobotProtocol::RobotProtocol() : m_pModbusServer(nullptr) , m_bServerRunning(false) , m_nPort(502) , m_robotStatus(STATUS_DISCONNECTED) { } RobotProtocol::~RobotProtocol() { Deinitialize(); } int RobotProtocol::Initialize(uint16_t port) { if (m_bServerRunning) { LOG_WARNING("Server is already running\n"); return SUCCESS; } m_nPort = port; // 创建ModbusTCP服务器实例 bool bRet = IYModbusTCPServer::CreateInstance(&m_pModbusServer); LOG_DEBUG("Create ModbusTCP server %s \n", bRet ? "success" : "failed"); m_bServerRunning = bRet; // 设置ModbusTCP回调函数 if (m_pModbusServer) { // 设置写线圈回调 m_pModbusServer->setWriteCoilsCallback([this](uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint8_t* values) { return this->OnWriteCoils(unitId, startAddress, quantity, values); }); // 设置写寄存器回调 m_pModbusServer->setWriteRegistersCallback([this](uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values) { return this->OnWriteRegisters(unitId, startAddress, quantity, values); }); // 设置连接状态回调 m_pModbusServer->setConnectionStatusCallback([this](bool connected) { this->OnModbusTCPConnectionChanged(connected); }); } int nRet = m_pModbusServer->start(m_nPort); ERR_CODE_RETURN(nRet); // 设置初始状态 m_robotStatus = STATUS_CONNECTED; // 设置初始工作状态为空闲 SetWorkStatus(WORK_STATUS_IDLE); LOG_INFO("ModbusTCP service initialization completed\n"); return SUCCESS; } void RobotProtocol::Deinitialize() { LOG_DEBUG("Stop ModbusTCP service\n"); // 停止ModbusTCP服务器 StopModbusTCPServer(); // 重置状态 m_robotStatus = STATUS_DISCONNECTED; m_bServerRunning = false; LOG_INFO("ModbusTCP service stopped\n"); } int RobotProtocol::SetMultiTargetData(const MultiTargetData& multiTargetData) { // 数据格式: count + 每个目标的{id,status,width,depth}数据(每个数据占2个寄存器) std::vector data; // 限制最大目标数量 size_t actualCount = multiTargetData.targets.size() > 5 ? 5 : multiTargetData.targets.size(); data.resize(actualCount * 16); memset(data.data(), 0, data.size() * sizeof(uint16_t)); // 定义一个辅助函数来转换uint32_t到ModbusTCP寄存器顺序大端格式 auto uint32ToBigEndian = [&](uint16_t addr, uint32_t value) { // ModbusTCP寄存器顺序大端:高16位寄存器在前,低16位寄存器在后 data[addr] = (value >> 16) & 0xFFFF; // 高16位寄存器 data[addr+1] = value & 0xFFFF; // 低16位寄存器 }; // 定义一个辅助函数来转换float到ModbusTCP寄存器顺序大端格式 auto floatToBigEndian = [&](uint16_t addr, float value) { uint32_t intValue; memcpy(&intValue, &value, sizeof(float)); // ModbusTCP寄存器顺序大端:高16位寄存器在前,低16位寄存器在后 data[addr] = (intValue >> 16) & 0xFFFF; // 高16位寄存器 data[addr+1] = intValue & 0xFFFF; // 低16位寄存器 }; // 定义一个辅助函数来转换uint16_t到ModbusTCP寄存器 auto uint16ToBigEndian = [&](uint16_t addr, uint16_t value) { data[addr] = value; // uint16_t直接存储 }; // 从第二个寄存器开始存储目标数据 count [{id,status,width,depth}, {id,status,width,depth}] for (size_t i = 0; i < actualCount; i++) { uint16_t addr = i * RESULT_OFFSET_ADDR; const TargetResult& target = multiTargetData.targets[i]; // 按照 id, status, width, depth 的顺序存储每个目标的数据 uint32ToBigEndian(addr, target.id); // ID (2个寄存器) uint16ToBigEndian(addr+2, target.status); // Status (1个寄存器) floatToBigEndian(addr+3, target.width); // Width (2个寄存器) floatToBigEndian(addr+5, target.depth); // Depth (2个寄存器) } m_pModbusServer->updateHoldingRegisters(DETECT_RESULT_ADDR, data); return SUCCESS; } RobotProtocol::RobotStatus RobotProtocol::GetDetectionStatus() const { return m_robotStatus; } void RobotProtocol::SetConnectionCallback(const ConnectionCallback& callback) { m_connectionCallback = callback; } void RobotProtocol::SetWorkSignalCallback(const WorkSignalCallback& callback) { m_workSignalCallback = callback; } void RobotProtocol::SetSystemControlCallback(const std::function& callback) { m_systemControlCallback = callback; } bool RobotProtocol::IsRunning() const { return m_bServerRunning; } int RobotProtocol::SetWorkStatus(uint16_t status) { LOG_DEBUG("Set work status to: %d\n", status); if (!m_pModbusServer) { LOG_ERROR("ModbusTCP server not initialized\n"); return ERR_CODE(DEV_NO_OPEN); } // 更新STATUS_ADDR地址的寄存器值 std::vector statusData; statusData.push_back(status); m_pModbusServer->updateHoldingRegisters(STATUS_ADDR, statusData); const char* statusStr = ""; switch(status) { case WORK_STATUS_IDLE: statusStr = "空闲"; break; case WORK_STATUS_WORKING: statusStr = "工作中"; break; case WORK_STATUS_BUSY: statusStr = "忙碌"; break; default: statusStr = "未知状态"; break; } LOG_INFO("Work status updated to: %d (%s)\n", status, statusStr); return SUCCESS; } int RobotProtocol::ClearDetectionData() { LOG_INFO("Clearing detection result data in Modbus registers\n"); if (!m_pModbusServer) { LOG_ERROR("ModbusTCP server not initialized\n"); return ERR_CODE(DEV_NO_OPEN); } // 清空检测结果数据区域(地址1-80,共5个撕裂信息,每个16个寄存器) // 总共需要清空 5 * 16 = 80 个寄存器 std::vector clearData(80, 0); // 创建80个值为0的寄存器 m_pModbusServer->updateHoldingRegisters(DETECT_RESULT_ADDR, clearData); LOG_INFO("Detection result data cleared (registers 1-80)\n"); return SUCCESS; } void RobotProtocol::StopModbusTCPServer() { LOG_DEBUG("Stop ModbusTCP server\n"); if (m_pModbusServer) { // 释放资源 delete m_pModbusServer; m_pModbusServer = nullptr; } m_bServerRunning = false; LOG_INFO("ModbusTCP server stopped\n"); } IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteCoils(uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint8_t* values) { return IYModbusTCPServer::ErrorCode::ILLEGAL_FUNCTION; } IYModbusTCPServer::ErrorCode RobotProtocol::OnWriteRegisters(uint8_t unitId, uint16_t startAddress, uint16_t quantity, const uint16_t* values) { // 只允许写入地址0(系统状态寄存器) if (startAddress != STATUS_ADDR) { LOG_WARNING("Attempt to write to read-only address: %d\n", startAddress); return IYModbusTCPServer::ErrorCode::ILLEGAL_DATA_ADDRESS; } // 只允许写入单个寄存器 if (quantity != 1) { LOG_WARNING("Invalid quantity for status register write: %d\n", quantity); return IYModbusTCPServer::ErrorCode::ILLEGAL_DATA_VALUE; } if (!values) { LOG_ERROR("Null values pointer in write registers\n"); return IYModbusTCPServer::ErrorCode::SERVER_FAILURE; } uint16_t command = values[0]; // 验证命令值是否有效(0-停止, 1-开始, 2-复位) if (command > 2) { LOG_WARNING("Invalid system control command: %d\n", command); return IYModbusTCPServer::ErrorCode::ILLEGAL_DATA_VALUE; } LOG_INFO("Received system control command via ModbusTCP: %d\n", command); // 调用系统控制回调 if (m_systemControlCallback) { m_systemControlCallback(command); LOG_DEBUG("System control callback executed for command: %d\n", command); } else { LOG_WARNING("System control callback not set\n"); } return IYModbusTCPServer::ErrorCode::SUCCESS; } void RobotProtocol::OnModbusTCPConnectionChanged(bool connected) { }