#include "LowerCommManager.h" #include "PowerManger.h" #include "driver.h" #include "udpcomm/udpComm.h" bool _ListenCB(void * pParam) { LowerCommManager* pMe = (LowerCommManager* )pParam; return pMe->listenThreadFunc(); } LowerCommManager::LowerCommManager(PowerManger* pm, long myPort, long ccuPort, const std::string& cccHost){ m_pm = pm; m_udpComm = new udpComm(); m_port = myPort; m_udpComm->ccuHost = cccHost; m_udpComm->ccuPort = ccuPort; m_udpComm->udpScoket = new XPCUdpSocket(m_port); std::cout << MOOS::ConsoleColours::yellow() << "╔════════════════════════╗" << MOOS::ConsoleColours::reset() << std::endl; std::cout << MOOS::ConsoleColours::yellow() << "║ [LOCAL PORT] " << MOOS::ConsoleColours::cyan() << m_port << MOOS::ConsoleColours::yellow() << std::setw(15) << " ║" << MOOS::ConsoleColours::reset() << std::endl; std::cout << MOOS::ConsoleColours::yellow() << "║ [CCU HOST ] " << MOOS::ConsoleColours::cyan() << m_udpComm->ccuHost << MOOS::ConsoleColours::yellow() << std::setw(8) << " ║" << MOOS::ConsoleColours::reset() << std::endl; std::cout << MOOS::ConsoleColours::yellow() << "║ [CCU PORT ] " << MOOS::ConsoleColours::cyan() << m_udpComm->ccuPort << MOOS::ConsoleColours::yellow() << std::setw(15) << " ║" << MOOS::ConsoleColours::reset() << std::endl; std::cout << MOOS::ConsoleColours::yellow() << "╚════════════════════════╝" << MOOS::ConsoleColours::reset() << std::endl; } LowerCommManager::~LowerCommManager(){ try { stopListenThread(); if (m_udpComm) { delete m_udpComm; m_udpComm = nullptr; } } catch (...) { cerr << "Error during cleanup" << endl; } } bool LowerCommManager::initUdpComm(){ if (m_udpComm->udpScoket) { try { std::cout << MOOS::ConsoleColours::yellow() << "Attempting to bind UDP socket..." << MOOS::ConsoleColours::reset() << std::endl; m_udpComm->udpScoket->vBindSocket(); // 可能会抛出 XPCException 或其他 std::exception std::cout << MOOS::ConsoleColours::green() << "UDP bind succeeded!" << MOOS::ConsoleColours::reset() << std::endl; LOG_F(INFO, "UDP bind succeeded!"); } catch (const std::exception& e) { std::cerr << MOOS::ConsoleColours::red() << "[UDP Bind Failed] Exception: " << e.what() << MOOS::ConsoleColours::reset() << std::endl; LOG_F(ERROR, "UDP bind failed: %s", e.what()); return false; } catch (...) { std::cerr << MOOS::ConsoleColours::red() << "[UDP Bind Failed] Unknown exception occurred!" << MOOS::ConsoleColours::reset() << std::endl; LOG_F(ERROR, "Unknown exception occurred during UDP bind"); return false; } } else { std::cerr << MOOS::ConsoleColours::red() << "[UDP Init Failed] udpSocket is null!" << MOOS::ConsoleColours::reset() << std::endl; LOG_F(ERROR, "udpSocket is null!"); return false; } return true; } void LowerCommManager::setLocalPort(long port){ if (port <= 0 || port == m_port) return; m_port = port; if (m_udpComm && m_udpComm->udpScoket) { // 套接字构造时即记录接收端口,改端口须重建(此时尚未 bind,重建安全) delete m_udpComm->udpScoket; m_udpComm->udpScoket = new XPCUdpSocket(m_port); } } void LowerCommManager::setCcuAddress(const std::string& host, long port){ m_ccuHost = host; m_ccuPort = port; if (m_udpComm) { m_udpComm->ccuHost = host; m_udpComm->ccuPort = port; } } void LowerCommManager::setCommLogger(ICommLogger* logger) { if (m_udpComm) m_udpComm->setCommLogger(logger); } void LowerCommManager::processPeriodicTasks() { ccuColCmd cmd; { std::lock_guard lock(m_pm->m_stateMutex); cmd = m_pm->m_CcuColCmd; } sendCcuCommand(cmd); m_pm->m_db->insertData(cmd); //延时5ms usleep(5000); auto devStatus = m_pm->m_systemData->getDeviceCommonStatus(); if(devStatus.dis_hv_c1.isTimeout ) { disHighVolBusCmd clr1{}; m_udpComm->sendDisSysCmd(clr1); MOOSPause(200); } if(devStatus.dis_lv_c1.isTimeout ) { disHighBVolBusCmd clr3{}; m_udpComm->sendDisSysCmd(clr3); MOOSPause(200); } m_udpComm->clearMsgQueue(); } void LowerCommManager::operate_hold() { disHighVolBusCmd clr1{}; disHighAVolBusCmd clr2{}; disHighBVolBusCmd clr3{}; disLowBusCmd clr4{}; m_udpComm->sendDisSysCmd(clr1); MOOSPause(200); m_udpComm->sendDisSysCmd(clr2); MOOSPause(200); m_udpComm->sendDisSysCmd(clr3); MOOSPause(200); m_udpComm->sendDisSysCmd(clr4); } bool LowerCommManager::sendCcuCommand(const ccuColCmd cmd){ // m_pm->m_db->insertCcuSysCmd(cmd); if(!m_udpComm->sendCcuColCmd(cmd)) cout << "send ccu command failed!" << endl; return true; } bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){ //根据目标状态进行断路器操作 //a. 高压母线的断路器 disHighVolBusCmd a; a.fuelCellCircuitBreaker = getBreakerOption(cmd.bus1Breaker.fuelCellCircuitBreaker); a.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(cmd.bus1Breaker.lithiumBatteryGroupInstrumentCircuitBreaker); a.dcDc5ModuleCircuitBreaker = getBreakerOption(cmd.bus1Breaker.dcDc5ModuleCircuitBreaker); a.powerLithiumBatteryCircuitBreaker = getBreakerOption(cmd.bus1Breaker.powerLithiumBatteryCircuitBreaker); a.propulsionMotorCircuitBreaker = getBreakerOption(cmd.bus1Breaker.propulsionMotorCircuitBreaker); a.bowHighVoltageDistributionBoxCircuitBreaker = getBreakerOption(cmd.bus1Breaker.bowHighVoltageDistributionBoxCircuitBreaker); a.tyzReservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.tyzReservedCircuitBreaker); a.sternFTDevice45CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternFTDevice45CircuitBreaker); a.sternRudderSwitch1CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternRudderSwitch1CircuitBreaker); a.sternRudderSwitch2CircuitBreaker = getBreakerOption(cmd.bus1Breaker.sternRudderSwitch2CircuitBreaker); a.reservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.reservedCircuitBreaker); a.fbReservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.fbReservedCircuitBreaker); a.dcdc5Module = getBreakerOption(cmd.bus1Breaker.dcdcmodel); a.coolingSystem = getBreakerOption(cmd.bus1Breaker.coolingSystem); m_udpComm->sendDisSysCmd(a); m_pm->m_db->insertData(a); usleep(5000); //b. 高压汇流排A断路器 disHighAVolBusCmd b; b.bowFTDevice123CircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowFTDevice123CircuitBreaker); b.actuatorCircuitBreaker = getBreakerOption(cmd.bus2Breaker.actuatorCircuitBreaker); b.mastSteeringGearControlBoxCircuitBreaker = getBreakerOption(cmd.bus2Breaker.mastSteeringGearControlBoxCircuitBreaker); b.xczCircuitBreaker = getBreakerOption(cmd.bus2Breaker.xczCircuitBreaker); b.bowRudderControlBoxCircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowRudderControlBoxCircuitBreaker); b.openWaterCoverStartCylinderCircuitBreaker = getBreakerOption(cmd.bus2Breaker.openWaterCoverStartCylinderCircuitBreaker); m_udpComm->sendDisSysCmd(b); m_pm->m_db->insertData(b); usleep(5000); //c. 低压主母线断路器 disHighBVolBusCmd c; c.lithiumBatteryGroupInstrumentCircuitBreaker = 0x55; c.bowLowVoltageDistributionBoxCircuitBreaker = 0xAA; c.unit4InstrumentDC48VCircuitBreaker = 0xAA; c.dcC1DCDistributionPanelCircuitBreaker = 0xAA; c.reservedCircuitBreaker1 = 0xAA; c.reservedCircuitBreaker2 = 0xAA; c.emergencyLithiumBatteryGroup2CircuitBreaker = 0xAA; m_udpComm->sendDisSysCmd(c); m_pm->m_db->insertData(c); usleep(5000); //d. 闭合低压汇流排断路器 disLowBusCmd d; d.unit1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit1CircuitBreaker); d.unit2CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit2CircuitBreaker); d.unit3CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit3CircuitBreaker); d.unit5CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit5CircuitBreaker); d.bowPZDeviceCircuitBreaker = getBreakerOption(cmd.bus4Breaker.bowPZDeviceCircuitBreaker); d.reservedCircuitBreaker1 = getBreakerOption(cmd.bus4Breaker.reservedCircuitBreaker1); d.reservedCircuitBreaker2 = getBreakerOption(cmd.bus4Breaker.reservedCircuitBreaker2); d.emergencyLithiumBatteryGroup1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.emergencyLithiumBatteryGroup1CircuitBreaker); m_udpComm->sendDisSysCmd(d); m_pm->m_db->insertData(d); usleep(5000); return true; } void LowerCommManager::clearMsgQueue(){ m_udpComm->clearMsgQueue(); } bool LowerCommManager::updatePoweSystemStates(){ // std::cout << "updatePoweSystemStates" << std::endl; if(!m_udpComm->m_qReceiveCcuStateBuffer.empty()) { double time; if(m_udpComm->popMsgFormQueue(time, m_CcuCurrentState)) { ccuState local = m_CcuCurrentState.data; { std::lock_guard lock(m_pm->m_stateMutex); m_pm->m_pmCurrentState.ccustate = local; } m_pm->m_db->insertData(local); //写入数据库 msg_CcuStateFbMsg_Update_time = time; m_pm->m_systemData->updateSystemData(local); { std::lock_guard lock(m_pm->m_systemData->m_dataMutex); m_pm->m_systemData->device_common_status.ccu_status.lastUpdateTime = m_pm->m_lowerCommManager->msg_CcuStateFbMsg_Update_time; } } } if(!m_udpComm->m_qReceiveCcuSetParmBuffer.empty()) { double time; msg_CcuSetParmFbMsg setParmFb; if(m_udpComm->popMsgFormQueue(time, setParmFb)) { m_pm->m_db->insertData(setParmFb); //写入数据库 } } if(!m_udpComm->m_qReceiveDisHighVolBusBuffer.empty()) { double time; if(m_udpComm->popMsgFormQueue(time, m_disHighVolBusCurrentState)) { disHighVolBusState local = m_disHighVolBusCurrentState.data; { std::lock_guard lock(m_pm->m_stateMutex); m_pm->m_pmCurrentState.bus1State = local; disBus1Breaker pdis1{}; pdis1.fuelCellCircuitBreaker = (local.fuelCellCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.powerLithiumBatteryCircuitBreaker = (local.powerLithiumBatteryCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.propulsionMotorCircuitBreaker = (local.propulsionMotorCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.lithiumBatteryGroupInstrumentCircuitBreaker = (local.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.dcDc5ModuleCircuitBreaker = (local.dcDc5ModuleCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.bowHighVoltageDistributionBoxCircuitBreaker = (local.bowHighVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.sternFTDevice45CircuitBreaker = (local.sternFTDevice45CircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.sternRudderSwitch1CircuitBreaker = (local.sternRudderSwitch1CircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.sternRudderSwitch2CircuitBreaker = (local.sternRudderSwitch2CircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.fbReservedCircuitBreaker = (local.fbReservedCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.tyzReservedCircuitBreaker = (local.tyzReservedCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.reservedCircuitBreaker = (local.reservedCircuitBreaker == BREAK_ON) ? 1 : 0; pdis1.paceholder = 0; m_pm->m_currentDisBreakerState.bus1Breaker = pdis1; } m_pm->m_db->insertData(local); //写入数据库 msg_disHighVolBusFbMsg_Update_time = time; m_pm->m_systemData->updateSystemData(local); { std::lock_guard lock(m_pm->m_systemData->m_dataMutex); m_pm->m_systemData->device_common_status.dis_hv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighVolBusFbMsg_Update_time; } } } if(!m_udpComm->m_qReceiveDisHighAVolBusBuffer.empty()) { double time; if(m_udpComm->popMsgFormQueue(time,m_disHighAVolBusCurrentState)) { disHighAVolBusState local = m_disHighAVolBusCurrentState.data; { std::lock_guard lock(m_pm->m_stateMutex); m_pm->m_pmCurrentState.bus2State = local; disBus2Breaker pdis2{}; pdis2.bowFTDevice123CircuitBreaker = (local.bowFTDevice123CircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.actuatorCircuitBreaker = (local.actuatorCircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.mastSteeringGearControlBoxCircuitBreaker = (local.mastSteeringGearControlBoxCircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.xczCircuitBreaker = (local.xczCircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.bowRudderControlBoxCircuitBreaker = (local.bowRudderControlBoxCircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.openWaterCoverStartCylinderCircuitBreaker = (local.openWaterCoverStartCylinderCircuitBreaker == BREAK_ON) ? 1 : 0; pdis2.paceholder = 0; m_pm->m_currentDisBreakerState.bus2Breaker = pdis2; } m_pm->m_db->insertData(local); //写入数据库 msg_disHighAVolBusFbMsg_Update_time = time; m_pm->m_systemData->updateSystemData(local); { std::lock_guard lock(m_pm->m_systemData->m_dataMutex); m_pm->m_systemData->device_common_status.dis_hv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighAVolBusFbMsg_Update_time; } } } if(!m_udpComm->m_qReceiveDisHighBVolBusBuffer.empty()) { double time; if(m_udpComm->popMsgFormQueue(time,m_disHighBVolBusCurrentState)) { disLowMainBusState local = m_disHighBVolBusCurrentState.data; { std::lock_guard lock(m_pm->m_stateMutex); m_pm->m_pmCurrentState.bus3State = local; disBus3Breaker pdis3{}; pdis3.lithiumBatteryGroupInstrumentCircuitBreaker = (local.lithiumBatteryGroupInstrumentCircuitBreaker == BREAK_ON) ? 1 : 0; pdis3.bowLowVoltageDistributionBoxCircuitBreaker = (local.bowLowVoltageDistributionBoxCircuitBreaker == BREAK_ON) ? 1 : 0; pdis3.unit4InstrumentDC48VCircuitBreaker = (local.unit4InstrumentDC48VCircuitBreaker == BREAK_ON) ? 1 : 0; pdis3.dcC1DCDistributionPanelCircuitBreaker = (local.dcC1DCDistributionPanelCircuitBreaker == BREAK_ON) ? 1 : 0; pdis3.reservedCircuitBreaker1 = (local.reservedCircuitBreaker1 == BREAK_ON) ? 1 : 0; pdis3.reservedCircuitBreaker2 = (local.reservedCircuitBreaker2 == BREAK_ON) ? 1 : 0; pdis3.emergencyLithiumBatteryGroup2CircuitBreaker = (local.emergencyLithiumBatteryGroup2CircuitBreaker == BREAK_ON) ? 1 : 0; pdis3.paceholder = 0; m_pm->m_currentDisBreakerState.bus3Breaker = pdis3; } m_pm->m_db->insertData(local); //写入数据库 msg_disHighBVolBusFbMsg_Update_time = time; m_pm->m_systemData->updateSystemData(local); { std::lock_guard lock(m_pm->m_systemData->m_dataMutex); m_pm->m_systemData->device_common_status.dis_lv_c1.lastUpdateTime = m_pm->m_lowerCommManager->msg_disHighBVolBusFbMsg_Update_time; } } } if(!m_udpComm->m_qReceiveDisLowBusBuffer.empty()) { double time; if(m_udpComm->popMsgFormQueue(time,m_disLowBusState)) { disLowBusState local = m_disLowBusState.data; { std::lock_guard lock(m_pm->m_stateMutex); m_pm->m_pmCurrentState.bus4State = local; disBus4Breaker pdis4{}; pdis4.unit1CircuitBreaker = (local.unit1CircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.unit2CircuitBreaker = (local.unit2CircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.unit3CircuitBreaker = (local.unit3CircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.unit5CircuitBreaker = (local.unit5CircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.bowPZDeviceCircuitBreaker = (local.bowPZDeviceCircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.reservedCircuitBreaker1 = (local.reservedCircuitBreaker1 == BREAK_ON) ? 1 : 0; pdis4.reservedCircuitBreaker2 = (local.reservedCircuitBreaker2 == BREAK_ON) ? 1 : 0; pdis4.emergencyLithiumBatteryGroup1CircuitBreaker = (local.emergencyLithiumBatteryGroup1CircuitBreaker == BREAK_ON) ? 1 : 0; pdis4.paceholder = 0; m_pm->m_currentDisBreakerState.bus4Breaker = pdis4; } m_pm->m_db->insertData(local); //写入数据库 msg_disLowBusFbMsg_Update_time = time; m_pm->m_systemData->updateSystemData(local); { std::lock_guard lock(m_pm->m_systemData->m_dataMutex); m_pm->m_systemData->device_common_status.dis_lv_c2.lastUpdateTime = m_pm->m_lowerCommManager->msg_disLowBusFbMsg_Update_time; } } } return true; } bool LowerCommManager::listenThreadFunc() { cout<udpScoket->iRecieveMessage(Buff, sizeof(Buff)); cout< 0) { try { if(m_udpComm->pushMsgToQueue(Buff, nRead)) { //更新当前状态 if(!updatePoweSystemStates()) { std::cerr << "Error updating power system states" << std::endl; } } else { for(int i=0; isError.size(); i++) { cout<sError[i] << MOOS::ConsoleColours::reset() << endl; } } } catch(const std::exception& e) { cerr << "Error processing message: " << e.what() << endl; } } // 打印通信错误信息 if(!m_udpComm->sError.empty()) { for(int i=0; isError.size(); i++) { cout<sError[i] << MOOS::ConsoleColours::reset() << endl; } m_udpComm->sError.clear(); } } catch(const XPCException& e) { cerr << "XPCException in listenThreadFunc" << endl; // 短暂休眠后继续尝试 MOOSPause(100); } catch(const std::exception& e) { cerr << "Exception in listenThreadFunc: " << e.what() << endl; MOOSPause(100); } catch(...) { cerr << "Unknown exception in listenThreadFunc" << endl; MOOSPause(100); } } return true; } void LowerCommManager::startListenThread() { if(!m_ListenThread.IsThreadRunning()) { m_ListenThread.Initialise(_ListenCB,this); m_ListenThread.Start(); std::cout << "LowerCommManager::startListenThread" << std::endl; } } void LowerCommManager::stopListenThread() { if(m_ListenThread.IsThreadRunning()) { m_ListenThread.Stop(); std::cout << "LowerCommManager::stopListenThread" << std::endl; } } char LowerCommManager::getBreakerOption(char cmd) { if(cmd ==1) return 0x55; else if(cmd ==0) return 0xAA; else return 0x00; } //================================================================================================================ // 高电压母线断路器操作函数 bool LowerCommManager::operate_HV_fuelCellCircuit_Breaker(char opt){ return operateBreakerGeneric( "HV_fuelCellCircuit_Breaker", opt, [&](disHighVolBusCmd& c){ c.fuelCellCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.fuelCellCircuitBreaker; } ); } bool LowerCommManager::operate_HV_powerLithiumBattery_Breaker(char opt){ return operateBreakerGeneric( "HV_powerLithiumBattery_Breaker", opt, [&](disHighVolBusCmd& c){ c.powerLithiumBatteryCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.powerLithiumBatteryCircuitBreaker; } ); } bool LowerCommManager::operate_HV_propulsionMotor_Breaker(char opt){ return operateBreakerGeneric( "HV_propulsionMotor_Breaker", opt, [&](disHighVolBusCmd& c){ c.propulsionMotorCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.propulsionMotorCircuitBreaker; } ); } bool LowerCommManager::operate_HV_lithiumBatteryMeter_Breaker(char opt){ return operateBreakerGeneric( "HV_lithiumBatteryMeter_Breaker", opt, [&](disHighVolBusCmd& c){ c.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupInstrumentCircuitBreaker; } ); } bool LowerCommManager::operate_HV_dcDc5Module_Breaker(char opt){ return operateBreakerGeneric( "HV_dcDc5Module_Breaker", opt, [&](disHighVolBusCmd& c){ c.dcDc5ModuleCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCircuitBreaker; } ); } bool LowerCommManager::operate_HV_bowHighVoltageBox_Breaker(char opt){ return operateBreakerGeneric( "HV_bowHighVoltageBox_Breaker", opt, [&](disHighVolBusCmd& c){ c.bowHighVoltageDistributionBoxCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCircuitBreaker; } ); } bool LowerCommManager::operate_HV_sternFt45_Breaker(char opt){ return operateBreakerGeneric( "HV_sternFt45_Breaker", opt, [&](disHighVolBusCmd& c){ c.sternFTDevice45CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.sternFTDevice45CircuitBreaker; } ); } bool LowerCommManager::operate_HV_sternRudder1_Breaker(char opt){ return operateBreakerGeneric( "HV_sternRudder1_Breaker", opt, [&](disHighVolBusCmd& c){ c.sternRudderSwitch1CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1CircuitBreaker; } ); } bool LowerCommManager::operate_HV_sternRudder2_Breaker(char opt){ return operateBreakerGeneric( "HV_sternRudder2_Breaker", opt, [&](disHighVolBusCmd& c){ c.sternRudderSwitch2CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2CircuitBreaker; } ); } bool LowerCommManager::operate_HV_fbReserved_Breaker(char opt){ return operateBreakerGeneric( "HV_fbReserved_Breaker", opt, [&](disHighVolBusCmd& c){ c.fbReservedCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.fbReservedCircuitBreaker; } ); } bool LowerCommManager::operate_HV_tyzReserved_Breaker(char opt){ return operateBreakerGeneric( "HV_tyzReserved_Breaker", opt, [&](disHighVolBusCmd& c){ c.tyzReservedCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.tyzReservedCircuitBreaker; } ); } bool LowerCommManager::operate_HV_reserved_Breaker(char opt){ return operateBreakerGeneric( "HV_reserved_Breaker", opt, [&](disHighVolBusCmd& c){ c.reservedCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus1State.reservedCircuitBreaker; } ); } // bool LowerCommManager::operate_HV_dcDc5_Breaker(char opt){ // return operateBreakerGeneric( // "HV_dcDc5_Breaker", // opt, // [&](disHighVolBusCmd& c){ c.dcdc5Module = getBreakerOption(opt); }, // [&](){ return m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02); } // ); // } bool LowerCommManager::operate_HV_dcDc5_Breaker(char opt) { disHighVolBusCmd cmd{}; // 默认全零 double t0 = MOOSTime(); bool ok = false; const char* name = "DCDC Module"; LOG_F(INFO, "operate %s: opt=%d", name, opt); cmd.dcdc5Module = getBreakerOption(opt); m_udpComm->sendDisSysCmd(cmd); // ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1&(0x02); ok = m_pm->m_systemData->getDcdcStatus().workingStatus; MOOSPause(100); while ( !ok ) { if( m_pm->m_systemData->getDcdcStatus().workingStatus ) { ok = true; break; } if (!m_udpComm->sendDisSysCmd(cmd)) { LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name); ok = false; break; } if (MOOSTime() > t0 + 6) { LOG_F(ERROR, "operate %s: timeout", name); ok = false; break; } MOOSPause(200); } //继电器复位 disHighVolBusCmd clr{}; for (int i = 0; i < 3; ++i) { m_udpComm->sendDisSysCmd(clr); MOOSPause(200); } return ok; } // bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt){ // return operateBreakerGeneric( // "HV_coolingSystem_Breaker", // opt, // [&](disHighVolBusCmd& c){ c.coolingSystem = getBreakerOption(opt); }, // [&](){ return (m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x20) ? 0x55 : 0xAA; } // ); // } bool LowerCommManager::operate_HV_coolingSystem_Breaker(char opt) { disHighVolBusCmd cmd{}; // 默认全零 double t0 = MOOSTime(); bool ok = false; const char* name = "CoolingSystem"; LOG_F(INFO, "operate %s: opt=%d", name, opt); cmd.coolingSystem = getBreakerOption(opt); m_udpComm->sendDisSysCmd(cmd); // ok = m_pm->m_pmCurrentState.bus1State.dcDcFaultWord1 & 0x60; ok = m_pm->m_systemData->getDcdcStatus().coolingPump1Running || m_pm->m_systemData->getDcdcStatus().coolingPump2Running; MOOSPause(100); while ( !ok ) { if( (m_pm->m_systemData->getDcdcStatus().coolingPump1Running || m_pm->m_systemData->getDcdcStatus().coolingPump2Running) ) { ok = true; break; } if (!m_udpComm->sendDisSysCmd(cmd)) { LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name); ok = false; break; } if (MOOSTime() > t0 + 6) { LOG_F(ERROR, "operate %s: timeout", name); ok = false; break; } MOOSPause(200); } //继电器复位 disHighVolBusCmd clr{}; for (int i = 0; i < 3; ++i) { m_udpComm->sendDisSysCmd(clr); MOOSPause(200); } return ok; } // 高压汇流排断路器操作函数 bool LowerCommManager::operate_HVA_bowFTDevice123Circuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_bowFTDevice123Circuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.bowFTDevice123CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.bowFTDevice123CircuitBreaker; } ); } bool LowerCommManager::operate_HVA_actuatorCircuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_actuatorCircuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.actuatorCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.actuatorCircuitBreaker; } ); } bool LowerCommManager::operate_HVA_mastSteeringGearControlBoxCircuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_mastSteeringGearControlBoxCircuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.mastSteeringGearControlBoxCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCircuitBreaker; } ); } bool LowerCommManager::operate_HVA_xczCircuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_xczCircuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.xczCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.xczCircuitBreaker; } ); } bool LowerCommManager::operate_HVA_bowRudderControlBoxCircuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_bowRudderControlBoxCircuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.bowRudderControlBoxCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCircuitBreaker; } ); } bool LowerCommManager::operate_HVA_openWaterCoverStartCylinderCircuit_Breaker(char opt){ return operateBreakerGeneric( "HVA_openWaterCoverStartCylinderCircuit_Breaker", opt, [&](disHighAVolBusCmd& c){ c.openWaterCoverStartCylinderCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCircuitBreaker; } ); } // 仪表汇流排断路器操作函数 bool LowerCommManager::operate_LVA_unit1Circuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_unit1Circuit_Breaker", opt, [&](disLowBusCmd& c){ c.unit1CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.unit1CircuitBreaker; } ); } bool LowerCommManager::operate_LVA_unit2Circuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_unit2Circuit_Breaker", opt, [&](disLowBusCmd& c){ c.unit2CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.unit2CircuitBreaker; } ); } bool LowerCommManager::operate_LVA_unit3Circuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_unit3Circuit_Breaker", opt, [&](disLowBusCmd& c){ c.unit3CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.unit3CircuitBreaker; } ); } bool LowerCommManager::operate_LVA_unit5Circuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_unit5Circuit_Breaker", opt, [&](disLowBusCmd& c){ c.unit5CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.unit5CircuitBreaker; } ); } bool LowerCommManager::operate_LVA_bowPZDeviceCircuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_bowPZDeviceCircuit_Breaker", opt, [&](disLowBusCmd& c){ c.bowPZDeviceCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.bowPZDeviceCircuitBreaker; } ); } bool LowerCommManager::operate_LVA_reservedCircuit1_Breaker(char opt){ return operateBreakerGeneric( "LVA_reservedCircuit1_Breaker", opt, [&](disLowBusCmd& c){ c.reservedCircuitBreaker1 = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker1; } ); } bool LowerCommManager::operate_LVA_reservedCircuit2_Breaker(char opt){ return operateBreakerGeneric( "LVA_reservedCircuit2_Breaker", opt, [&](disLowBusCmd& c){ c.reservedCircuitBreaker2 = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.reservedCircuitBreaker2; } ); } bool LowerCommManager::operate_LVA_mergencyLithiumBatteryGroup1Circuit_Breaker(char opt){ return operateBreakerGeneric( "LVA_mergencyLithiumBatteryGroup1Circuit_Breaker", opt, [&](disLowBusCmd& c){ c.emergencyLithiumBatteryGroup1CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1CircuitBreaker; } ); } // 仪表母线断路器操作函数 bool LowerCommManager::operate_LV_lithiumBatteryGroupInstrumentCircuit_Breaker(char opt){ return operateBreakerGeneric( "lithiumBatteryGroupInstrumentCircuitBreaker", opt, [&](disLowMainBusCmd& c){ c.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCircuitBreaker; } ); } bool LowerCommManager::operate_LV_bowLowVoltageDistributionBoxCircuit_Breaker(char opt){ return operateBreakerGeneric( "bowLowVoltageDistributionBoxCircuitBreaker", opt, [&](disLowMainBusCmd& c){ c.bowLowVoltageDistributionBoxCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCircuitBreaker; } ); } bool LowerCommManager::operate_LV_unit4Dc48V_Breaker(char opt){ return operateBreakerGeneric( "unit4InstrumentDC48VCircuitBreaker", opt, [&](disLowMainBusCmd& c){ c.unit4InstrumentDC48VCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCircuitBreaker; } ); } bool LowerCommManager::operate_LV_dcC1Panel_Breaker(char opt){ return operateBreakerGeneric( "dcC1DCDistributionPanelCircuitBreaker", opt, [&](disLowMainBusCmd& c){ c.dcC1DCDistributionPanelCircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.dcC1DCDistributionPanelCircuitBreaker; } ); } bool LowerCommManager::operate_LV_reservedCircuit1_Breaker(char opt){ return operateBreakerGeneric( "reservedCircuitBreaker1", opt, [&](disLowMainBusCmd& c){ c.reservedCircuitBreaker1 = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker1; } ); } bool LowerCommManager::operate_LV_reservedCircuit2_Breaker(char opt){ return operateBreakerGeneric( "reservedCircuitBreaker2", opt, [&](disLowMainBusCmd& c){ c.reservedCircuitBreaker2 = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.reservedCircuitBreaker2; } ); } bool LowerCommManager::operate_LV_mergencyLithiumBatteryGroup2Circuit_Breaker(char opt){ return operateBreakerGeneric( "emergencyLithiumBatteryGroup2CircuitBreaker", opt, [&](disLowMainBusCmd& c){ c.emergencyLithiumBatteryGroup2CircuitBreaker = getBreakerOption(opt); }, [&](){ return m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2CircuitBreaker; } ); } // 通用模板 template bool LowerCommManager::operateBreakerGeneric( char const* name, char opt, std::function fillCmd, // 填 cmd 对应字段 std::function readState // 读 pmCurrentState 对应字段 ) { CmdT cmd{}; // 默认全零 double t0 = MOOSTime(); bool ok = false; LOG_F(INFO, "operate %s: opt=%d", name, opt); // 第一次发包 fillCmd(cmd); m_udpComm->sendDisSysCmd(cmd); MOOSPause(100); while ( !ok ) { StateT cur; { std::lock_guard lock(m_pm->m_stateMutex); cur = readState(); } if( cur == getBreakerOption(opt) ) { ok = true; break; } if (!m_udpComm->sendDisSysCmd(cmd)) { LOG_F(ERROR, "operate %s: sendDisSysCmd failed", name); ok = false; break; } if (MOOSTime() > t0 + 6) { LOG_F(ERROR, "operate %s: timeout", name); ok = false; break; } MOOSPause(200); } //继电器复位 CmdT clr{}; for (int i = 0; i < 3; ++i) { m_udpComm->sendDisSysCmd(clr); MOOSPause(200); } return ok; }