From 476be200257696be27f14c128819dbe38fdcf14c Mon Sep 17 00:00:00 2001 From: zhaojingkui <1553836110@qq.com> Date: Wed, 14 May 2025 10:02:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E6=AC=A1=E7=BA=A7?= =?UTF-8?q?=E9=85=8D=E7=94=B5=E5=8D=8F=E8=AE=AE,=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/pPMtest.moos | 9 - data/msg/uPower_fcsState_st.json | 31 +- data/msg/uPower_liBatState_st.json | 39 +- src/pPowerManger/CMakeLists.txt | 22 +- src/pPowerManger/LowerCommManager.cpp | 120 ++++- src/pPowerManger/LowerCommManager.h | 1 + src/pPowerManger/PowerManger.cpp | 17 +- src/pPowerManger/PowerManger.h | 9 +- src/pPowerManger/UpperCommManager.cpp | 492 ++---------------- src/pPowerManger/UpperCommManager.h | 23 +- src/pPowerManger/ccuUdpMsg.h | 6 +- src/pPowerManger/driver.cpp | 190 ++++--- src/pPowerManger/driver.h | 11 +- src/pPowerManger/fsm/CruiseMode.cpp | 20 + src/pPowerManger/fsm/DJMode.cpp | 15 + src/pPowerManger/fsm/FaultState.cpp | 19 + src/pPowerManger/fsm/FloatAdjust.cpp | 21 + src/pPowerManger/fsm/FloatDown.cpp | 20 + src/pPowerManger/fsm/HighSpeedMode.cpp | 14 + src/pPowerManger/fsm/InitState.cpp | 9 + .../{ => fsm}/PowerManagerFsm.cpp | 337 +----------- .../{ => fsm}/PowerManagerFsm.hpp | 32 +- src/pPowerManger/fsm/RemoteControl.cpp | 16 + src/pPowerManger/fsm/ShoreBasedReady.cpp | 21 + src/pPowerManger/fsm/StandbyState.cpp | 55 ++ src/pPowerManger/fsm/SurfaceSurvey.cpp | 14 + src/pPowerManger/fsm/UnderwaterSurvey.cpp | 15 + src/pPowerManger/fsm/WaterBasedReady.cpp | 20 + src/pPowerManger/{ => fsm}/tinyfsm.hpp | 0 src/pPowerManger/msg/uDevice_secdistState.h | 451 ++++++++++++++++ src/pPowerManger/msg/uPower_currentState_st.h | 81 +++ src/pPowerManger/msg/uPower_disSysState.h | 55 ++ src/pPowerManger/msg/uPower_equInsState.h | 220 ++++++++ src/pPowerManger/msg/uPower_equState.h | 26 + src/pPowerManger/msg/uPower_fcsState.h | 133 +++++ src/pPowerManger/msg/uPower_liBatState.h | 137 +++++ src/pPowerManger/msg/uPower_pmState.h | 63 +++ src/pPowerManger/pmSysvariable.h | 258 ++++----- test/disSysTest.zip | Bin 0 -> 61619 bytes test/disSysTest/PowerManagerApp.py | 351 ++++++++----- test/disSysTest/db.py | 11 +- test/disSysTest/test.py | 55 +- test/disSysTest/udpMsg.py | 16 +- 43 files changed, 2229 insertions(+), 1226 deletions(-) delete mode 100644 bin/pPMtest.moos create mode 100644 src/pPowerManger/fsm/CruiseMode.cpp create mode 100644 src/pPowerManger/fsm/DJMode.cpp create mode 100644 src/pPowerManger/fsm/FaultState.cpp create mode 100644 src/pPowerManger/fsm/FloatAdjust.cpp create mode 100644 src/pPowerManger/fsm/FloatDown.cpp create mode 100644 src/pPowerManger/fsm/HighSpeedMode.cpp create mode 100644 src/pPowerManger/fsm/InitState.cpp rename src/pPowerManger/{ => fsm}/PowerManagerFsm.cpp (86%) rename src/pPowerManger/{ => fsm}/PowerManagerFsm.hpp (98%) create mode 100644 src/pPowerManger/fsm/RemoteControl.cpp create mode 100644 src/pPowerManger/fsm/ShoreBasedReady.cpp create mode 100644 src/pPowerManger/fsm/StandbyState.cpp create mode 100644 src/pPowerManger/fsm/SurfaceSurvey.cpp create mode 100644 src/pPowerManger/fsm/UnderwaterSurvey.cpp create mode 100644 src/pPowerManger/fsm/WaterBasedReady.cpp rename src/pPowerManger/{ => fsm}/tinyfsm.hpp (100%) create mode 100644 src/pPowerManger/msg/uDevice_secdistState.h create mode 100644 src/pPowerManger/msg/uPower_currentState_st.h create mode 100644 src/pPowerManger/msg/uPower_disSysState.h create mode 100644 src/pPowerManger/msg/uPower_equInsState.h create mode 100644 src/pPowerManger/msg/uPower_equState.h create mode 100644 src/pPowerManger/msg/uPower_fcsState.h create mode 100644 src/pPowerManger/msg/uPower_liBatState.h create mode 100644 src/pPowerManger/msg/uPower_pmState.h create mode 100644 test/disSysTest.zip diff --git a/bin/pPMtest.moos b/bin/pPMtest.moos deleted file mode 100644 index 3083268..0000000 --- a/bin/pPMtest.moos +++ /dev/null @@ -1,9 +0,0 @@ -//------------------------------------------------ -// pPMtest config block - -ProcessConfig = pPMtest -{ - AppTick = 4 - CommsTick = 4 -} - diff --git a/data/msg/uPower_fcsState_st.json b/data/msg/uPower_fcsState_st.json index 31141fb..ec747fa 100644 --- a/data/msg/uPower_fcsState_st.json +++ b/data/msg/uPower_fcsState_st.json @@ -1,30 +1 @@ -{ - "backpressure1_fp32": 0.0, - "backpressure2_fp32": 0.0, - "ch4oConcent1_fp32": 0.0, - "ch4oConcent2_fp32": 0.0, - "ch4o_fp32": 0.0, - "excTemp_fp32": 0.0, - "faultCode1_uint16": 0, - "faultCode2_uint16": 0, - "faultCode3_uint16": 0, - "fcuCurIns_fp32": 0.0, - "fcuCurPower_fp32": 0.0, - "fcuCur_fp32": 0.0, - "fcuFaultLeve_uint8": 0, - "fcuOutIns_fp32": 0.0, - "fcuOutPower_fp32": 0.0, - "fcuState_uint8": 0, - "fcuVolIns_fp32": 0.0, - "fcuVolPower_fp32": 0.0, - "fcuVol_fp32": 0.0, - "flameDet_uint8": 0, - "h2Concent1_fp32": 0.0, - "h2Concent2_fp32": 0.0, - "o2Concent1_fp32": 0.0, - "o2Concent2_fp32": 0.0, - "o2Level_fp32": 0.0, - "o2_fp32": 0.0, - "powLimit_fp32": 0.0, - "powerGen_fp32": 0.0 -} \ No newline at end of file +null \ No newline at end of file diff --git a/data/msg/uPower_liBatState_st.json b/data/msg/uPower_liBatState_st.json index b3e9fd4..ec747fa 100644 --- a/data/msg/uPower_liBatState_st.json +++ b/data/msg/uPower_liBatState_st.json @@ -1,38 +1 @@ -{ - "fcuCurToInsLimit1_uint8": 0, - "fcuCurToinsLimit2_uint8": 0, - "insBatCurElect_uint16": 0, - "insBatLimit_uint16": 0, - "insBatSoc_uint8": 0, - "insBatTotalElect_uint16": 0, - "insChargeState_uint8": 0, - "insCurSocHold1_uint8": 0, - "insCurSocHold2_uint8": 0, - "insCurSocHold3_uint8": 0, - "insCurrent_uint16": 0, - "insLinkVol_uint16": 0, - "insNegRelayState_uint8": 0, - "insNegRes_uint16": 0, - "insPackVol_uint16": 0, - "insPosRelayState_uint8": 0, - "insPosRes_uint16": 0, - "insfaultCode_uint8": 0, - "powBatCurElect_uint16": 0, - "powBatSoc_uint8": 0, - "powBatTotalElect_uint16": 0, - "powChargeState_uint8": 0, - "powCurSocHold1_uint8": 0, - "powCurSocHold2_uint8": 0, - "powCurSocHold3_uint8": 0, - "powCurToInsLimit1_uint8": 0, - "powCurToinsLimit2_uint8": 0, - "powCur_uint16": 0, - "powLinkVol_uint16": 0, - "powNegRelayState_uint8": 0, - "powNegRes_uint16": 0, - "powPosRelayState_uint8": 0, - "powPosRes_uint16": 0, - "powerBatLimit_uint16": 0, - "powerPackVol_uint16": 0, - "powfaultCode_uint8": 0 -} \ No newline at end of file +null \ No newline at end of file diff --git a/src/pPowerManger/CMakeLists.txt b/src/pPowerManger/CMakeLists.txt index 4cef8d9..9d7b35d 100644 --- a/src/pPowerManger/CMakeLists.txt +++ b/src/pPowerManger/CMakeLists.txt @@ -18,8 +18,25 @@ endif (${WIN32}) # Find SQLite3 package # find_package(SQLite3 REQUIRED) +SET(FSMLIB_SRC + fsm/PowerManagerFsm.cpp # 更新静态库的源文件路径 + fsm/CruiseMode.cpp + fsm/DJMode.cpp + fsm/FaultState.cpp + fsm/FloatAdjust.cpp + fsm/FloatDown.cpp + fsm/HighSpeedMode.cpp + fsm/InitState.cpp + fsm/RemoteControl.cpp + fsm/ShoreBasedReady.cpp + fsm/StandbyState.cpp + fsm/SurfaceSurvey.cpp + fsm/UnderwaterSurvey.cpp + fsm/WaterBasedReady.cpp +) + SET(SRC - PowerManagerFsm.cpp + ${FSMLIB_SRC} PowerManger.cpp PowerManger_Info.cpp udpComm.cpp @@ -55,9 +72,6 @@ SET(SQLITEDB_SRC SQLiteDB.cpp ) -SET(FSMLIB_SRC - PowerManagerFsm.cpp) - SET(DRIVER_SRC driver.cpp) diff --git a/src/pPowerManger/LowerCommManager.cpp b/src/pPowerManger/LowerCommManager.cpp index 0db30f3..7231908 100644 --- a/src/pPowerManger/LowerCommManager.cpp +++ b/src/pPowerManger/LowerCommManager.cpp @@ -77,8 +77,11 @@ bool LowerCommManager::initUdpComm(){ } void LowerCommManager::processPeriodicTasks() { sendCcuCommand(m_pm->m_CcuColCmd); + //延时5ms + usleep(5000); sendDisSysCommand(m_pm->m_targetDisBreakerState); m_udpComm->clearMsgQueue(); + } bool LowerCommManager::sendCcuCommand(const ccuColCmd cmd){ @@ -105,6 +108,7 @@ bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){ a.reservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.reservedCircuitBreaker); a.fbReservedCircuitBreaker = getBreakerOption(cmd.bus1Breaker.fbReservedCircuitBreaker); m_udpComm->sendDisSysCmd(a); + usleep(5000); //b. 高压汇流排A断路器 disHighAVolBusCmd b; b.bowFTDevice123CircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowFTDevice123CircuitBreaker); @@ -114,6 +118,7 @@ bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){ b.bowRudderControlBoxCircuitBreaker = getBreakerOption(cmd.bus2Breaker.bowRudderControlBoxCircuitBreaker); b.openWaterCoverStartCylinderCircuitBreaker = getBreakerOption(cmd.bus2Breaker.openWaterCoverStartCylinderCircuitBreaker); m_udpComm->sendDisSysCmd(b); + usleep(5000); //c. 高压汇流排B断路器 disHighBVolBusCmd c; c.lithiumBatteryGroupInstrumentCircuitBreaker = getBreakerOption(cmd.bus3Breaker.lithiumBatteryGroupInstrumentCircuitBreaker); @@ -124,6 +129,7 @@ bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){ c.reservedCircuitBreaker2 = getBreakerOption(cmd.bus3Breaker.reservedCircuitBreaker2); c.emergencyLithiumBatteryGroup2CircuitBreaker = getBreakerOption(cmd.bus3Breaker.emergencyLithiumBatteryGroup2CircuitBreaker); m_udpComm->sendDisSysCmd(c); + usleep(5000); //d. 闭合低压汇流排断路器 disLowBusCmd d; d.unit1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.unit1CircuitBreaker); @@ -135,6 +141,7 @@ bool LowerCommManager::sendDisSysCommand(const disSysBreakerList& cmd){ d.reservedCircuitBreaker2 = getBreakerOption(cmd.bus4Breaker.reservedCircuitBreaker2); d.emergencyLithiumBatteryGroup1CircuitBreaker = getBreakerOption(cmd.bus4Breaker.emergencyLithiumBatteryGroup1CircuitBreaker); m_udpComm->sendDisSysCmd(d); + usleep(5000); //将指令写入数据库 // m_pm->m_db->insertDisSysCmd(a); // m_pm->m_db->insertDisSysCmd(b); @@ -157,6 +164,8 @@ bool LowerCommManager::updatePoweSystemStates(){ m_udpComm->popMsgFormQueue(time,m_CcuCurrentState); m_pm->m_pmCurrentState.ccustate = m_CcuCurrentState.data; // m_db->insertCcuData(m_CcuCurrentState.data); //写入数据库 + //DEBUG + coutMsg(m_CcuCurrentState); msg_CcuStateFbMsg_Update_time = time; } if(!m_udpComm->m_qReceiveDisHighVolBusBuffer.empty()) @@ -256,7 +265,7 @@ bool LowerCommManager::listenThreadFunc() try { int nRead = m_udpComm->udpScoket->iRecieveMessage(Buff, sizeof(Buff)); - //cout< 0) { try { @@ -342,3 +351,112 @@ bool LowerCommManager::checkConnection() { m_pm->connectState =5; } + +void LowerCommManager::coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os){ + os << std::hex << std::setfill('0') << std::uppercase; + + os << "起始符1 (start1): 0x" << std::setw(2) << static_cast(p.header.start1) << "\n"; + os << "起始符2 (start2): 0x" << std::setw(2) << static_cast(p.header.start2) << "\n"; + os << "标识符 (identifier): 0x" << std::setw(4) << p.header.id << "\n"; + os << std::dec << "数据长度 (length): " << p.header.length << "\n"; + + + os << "运行模式 (fc_mode): 0x" << std::hex << std::setw(2) << static_cast(p.data.fc_mode) << "\n"; + os << "燃料电池状态 (fc_status): 0x" << std::setw(2) << static_cast(p.data.fc_status) << "\n"; + os << "故障等级 (fc_fault_level): 0x" << std::setw(2) << static_cast(p.data.fc_fault_level) << "\n"; + + os << std::dec; + os << "输出功率限制 (output_power_limit): " << p.data.output_power_limit << " W\n"; + os << "累计发电时间 (total_generation_time): " << p.data.total_generation_time * 0.1 << " 小时\n"; + os << "发电总功率 (total_generation_power): " << p.data.total_generation_power << " W\n"; + os << "一级故障字 (fault_level_1): 0x" << std::hex << p.data.fault_level_1 << "\n"; + os << "二级故障字 (fault_level_2): 0x" << p.data.fault_level_2 << "\n"; + os << "三级故障字 (fault_level_3): 0x" << p.data.fault_level_3 << "\n"; + os << "四级故障字 (fault_level_4): 0x" << p.data.fault_level_4 << "\n"; + + os << std::dec; + os << "储氢剩余容量 (hydrogen_capacity): " << static_cast(p.data.hydrogen_capacity) << "%\n"; + os << "液氧剩余容量 (liquid_oxygen_capacity): " << static_cast(p.data.liquid_oxygen_capacity) << "%\n"; + os << "钯膜最高温度 (palladium_temp): " << p.data.palladium_temp << " ℃\n"; + os << "主水路压力 (main_pipe_pressure): " << p.data.main_pipe_pressure * 0.01 << " kPa\n"; + os << "辅水路压力 (aux_pipe_pressure): " << p.data.aux_pipe_pressure * 0.01 << " kPa\n"; + + os << "舱室压力1 (cabin_pressure1): " << p.data.cabin_pressure1 * 0.01 << " kPa\n"; + os << "舱室压力2 (cabin_pressure2): " << p.data.cabin_pressure2 * 0.01 << " kPa\n"; + os << "舱室温度1 (cabin_temp1): " << p.data.cabin_temp1 * 0.01 << " ℃\n"; + os << "舱室温度2 (cabin_temp2): " << p.data.cabin_temp2 * 0.01 << " ℃\n"; + os << "舱室湿度1 (cabin_humidity1): " << p.data.cabin_humidity1 * 0.01 << " %RH\n"; + os << "舱室湿度2 (cabin_humidity2): " << p.data.cabin_humidity2 * 0.01 << " %RH\n"; + + os << "火焰探测器1状态 (flame_detector1): 0x" << std::hex << static_cast(p.data.flame_detector1) << "\n"; + os << "火焰探测器2状态 (flame_detector2): 0x" << static_cast(p.data.flame_detector2) << "\n"; + + os << std::dec; + os << "氢气浓度1 (h2_concentration1): " << p.data.h2_concentration1 * 0.01 << "% LEL\n"; + os << "氢气浓度2 (h2_concentration2): " << p.data.h2_concentration2 * 0.01 << "% LEL\n"; + os << "氢气浓度3 (h2_concentration3): " << p.data.h2_concentration3 * 0.01 << "% LEL\n"; + os << "氧气浓度1 (o2_concentration1): " << p.data.o2_concentration1 * 0.01 << "% LEL\n"; + os << "氧气浓度2 (o2_concentration2): " << p.data.o2_concentration2 * 0.01 << "% LEL\n"; + os << "甲醇浓度1 (ch3oh_concentration1): " << p.data.ch3oh_concentration1 * 0.01 << "% LEL\n"; + os << "甲醇浓度2 (ch3oh_concentration2): " << p.data.ch3oh_concentration2 * 0.01 << "% LEL\n"; + + for (int i = 0; i < 18; ++i) + os << "保留字段 reserved1[" << i << "]: 0x" << std::hex << p.data.reserved1[i] << "\n"; + + for (int i = 0; i < 6; ++i) + os << "动力电池报警标志 dyn_alarm_flag[" << i << "]: 0x" << std::hex << static_cast(p.data.dyn_alarm_flag[i]) << "\n"; + for (int i = 0; i < 6; ++i) + os << "仪表电池报警标志 ins_alarm_flag[" << i << "]: 0x" << std::hex << static_cast(p.data.ins_alarm_flag[i]) << "\n"; + + os << "仪表正极/充电继电器状态 (ins_relay_status1): 0x" << std::hex << static_cast(p.data.ins_relay_status1) << "\n"; + os << "仪表预充/负极继电器状态 (ins_relay_status2): 0x" << static_cast(p.data.ins_relay_status2) << "\n"; + os << "动力正极/充电继电器状态 (dyn_relay_status1): 0x" << static_cast(p.data.dyn_relay_status1) << "\n"; + os << "动力预充/负极继电器状态 (dyn_relay_status2): 0x" << static_cast(p.data.dyn_relay_status2) << "\n"; + + os << std::dec; + os << "仪表最大放电功率 (ins_max_discharge_power): " << p.data.ins_max_discharge_power * 0.05 << " kW\n"; + os << "动力最大放电功率 (dyn_max_discharge_power): " << p.data.dyn_max_discharge_power * 0.05 << " kW\n"; + + os << "仪表SOC (ins_soc): " << static_cast(p.data.ins_soc) << "%\n"; + os << "动力SOC (dyn_soc): " << static_cast(p.data.dyn_soc) << "%\n"; + + os << "仪表电池总能量 (ins_total_energy): " << p.data.ins_total_energy << " kWh\n"; + os << "动力电池总能量 (dyn_total_energy): " << p.data.dyn_total_energy << " kWh\n"; + + os << "仪表输入功率 (ins_power_input): " << p.data.ins_power_input << " kW\n"; + os << "动力输入功率 (dyn_power_input): " << p.data.dyn_power_input << " kW\n"; + + os << "仪表充电状态 (ins_charge_status): 0x" << std::hex << static_cast(p.data.ins_charge_status) << "\n"; + os << "动力充电状态 (dyn_charge_status): 0x" << static_cast(p.data.dyn_charge_status) << "\n"; + + os << std::dec; + os << "仪表LINK电压: " << p.data.ins_voltage_link * 0.01 << " V\n"; + os << "仪表PACK电压: " << p.data.ins_voltage_pack * 0.01 << " V\n"; + os << "仪表电流: " << p.data.ins_current * 0.01 << " A\n"; + os << "仪表正端绝缘电阻: " << p.data.ins_resistance_pos << " kΩ\n"; + os << "仪表负端绝缘电阻: " << p.data.ins_resistance_neg << " kΩ\n"; + os << "动力LINK电压: " << p.data.dyn_voltage_link * 0.01 << " V\n"; + os << "动力PACK电压: " << p.data.dyn_voltage_pack * 0.01 << " V\n"; + os << "动力电流: " << p.data.dyn_current * 0.01 << " A\n"; + os << "动力正端绝缘电阻: " << p.data.dyn_resistance_pos << " kΩ\n"; + os << "动力负端绝缘电阻: " << p.data.dyn_resistance_neg << " kΩ\n"; + + os << "仪表紧急状态 (ins_emergency_status): 0x" << std::hex << static_cast(p.data.ins_emergency_status) << "\n"; + os << "动力紧急状态 (dyn_emergency_status): 0x" << static_cast(p.data.dyn_emergency_status) << "\n"; + + for (int i = 0; i < 2; ++i) + os << "保留字段 reserved2[" << i << "]: 0x" << std::hex << static_cast(p.data.reserved2[i]) << "\n"; + for (int i = 0; i < 6; ++i) + os << "SOC门限值 ins_soc_threshold" << i+1 << ": 0x" << std::hex << static_cast(p.data.ins_soc_threshold1) << "\n"; + for (int i = 0; i < 4; ++i) + os << "功率限制 ins_power_limit" << i+1 << ": 0x" << std::hex << static_cast(p.data.ins_power_limit1) << "\n"; + + os << "设备在线状态1 (device_online_flag1): 0x" << std::hex << p.data.device_online_flag1 << "\n"; + os << "设备在线状态2 (device_online_flag2): 0x" << p.data.device_online_flag2 << "\n"; + + // os << "保留字段 reserved3: 0x" << p.data.reserved1 << "\n"; + os << "主机心跳 (reserved4): 0x" << p.data.heartbeat << "\n"; + os << "校验和 (checksum): 0x" << p.checkCode << "\n"; + + os << std::dec; +} \ No newline at end of file diff --git a/src/pPowerManger/LowerCommManager.h b/src/pPowerManger/LowerCommManager.h index cc75d78..f826c27 100644 --- a/src/pPowerManger/LowerCommManager.h +++ b/src/pPowerManger/LowerCommManager.h @@ -46,6 +46,7 @@ public: // 启动/停止监听线程 void startListenThread(); void stopListenThread(); + void coutMsg(const msg_CcuStateFbMsg& p, std::ostream& os = std::cout); //转换函数 char getBreakerOption(char cmd); diff --git a/src/pPowerManger/PowerManger.cpp b/src/pPowerManger/PowerManger.cpp index 68897a0..a01e260 100644 --- a/src/pPowerManger/PowerManger.cpp +++ b/src/pPowerManger/PowerManger.cpp @@ -126,6 +126,8 @@ bool PowerManger::Iterate() AppCastingMOOSApp::Iterate(); // 打印当前状态 // cout << " Current State : " << (int)PowerManagerFsm::current_state_ptr->getCurrentState(); + CycleTriggeredEvent cycleEvent; + PowerManagerFsm::dispatch(cycleEvent); faultLevel = getFaultLevel(); if (m_ticker++ % 5 == 0) { @@ -263,14 +265,15 @@ bool PowerManger::writeDataToDB() int PowerManger::checkError() { + //TODO:更新协议 //1.检查复合管控器状态 - if(m_pmCurrentState.ccustate.fcuGZ_1H != 0 || - m_pmCurrentState.ccustate.fcuGZ_1L != 0 || - m_pmCurrentState.ccustate.fcuGZ_2H != 0 || - m_pmCurrentState.ccustate.fcuGZ_2L != 0 || - m_pmCurrentState.ccustate.fcuGZ_3H != 0 || - m_pmCurrentState.ccustate.fcuGZ_3L != 0 || - m_pmCurrentState.ccustate.insEmergencyStatusWord != 0) + // if(m_pmCurrentState.ccustate.fcuGZ_1H != 0 || + // m_pmCurrentState.ccustate.fcuGZ_1L != 0 || + // m_pmCurrentState.ccustate.fcuGZ_2H != 0 || + // m_pmCurrentState.ccustate.fcuGZ_2L != 0 || + // m_pmCurrentState.ccustate.fcuGZ_3H != 0 || + // m_pmCurrentState.ccustate.fcuGZ_3L != 0 || + // m_pmCurrentState.ccustate.insEmergencyStatusWord != 0) return 0; //2.检查断路器状态 } diff --git a/src/pPowerManger/PowerManger.h b/src/pPowerManger/PowerManger.h index 31a7b41..6ebd1ed 100644 --- a/src/pPowerManger/PowerManger.h +++ b/src/pPowerManger/PowerManger.h @@ -31,16 +31,16 @@ #include "json/json.h" #include "udpComm.h" #include "pmSysvariable.h" -#include "PowerManagerFsm.hpp" +#include "fsm/PowerManagerFsm.hpp" // #include "SQLiteDB.h" #include "driver.h" #include "LowerCommManager.h" #include "UpperCommManager.h" -#define IPORT 5000 -#define CCUPORT 5001 -#define CCUHOST "127.0.0.1" +#define IPORT 5001 +#define CCUPORT 7000 +#define CCUHOST "192.168.0.140" #define MAX_UDP_PKT_SIZE 65535 #define SKEW_TOLERANCE 5 @@ -115,7 +115,6 @@ class PowerManger : public AppCastingMOOSApp LowerCommManager* m_lowerCommManager; UpperCommManager* m_upperCommManager; - // // 状态机实例 // PowerManagerFsm m_fsm; public: diff --git a/src/pPowerManger/UpperCommManager.cpp b/src/pPowerManger/UpperCommManager.cpp index 153253f..a947e7a 100644 --- a/src/pPowerManger/UpperCommManager.cpp +++ b/src/pPowerManger/UpperCommManager.cpp @@ -1,9 +1,9 @@ #include "UpperCommManager.h" #include "PowerManger.h" #include "driver.h" -#include "PowerManagerFsm.hpp" +#include "fsm/PowerManagerFsm.hpp" -UpperCommManager::UpperCommManager(PowerManger* pm) : m_pm(pm) {} +UpperCommManager::UpperCommManager(PowerManger* pm) : m_pm(pm) {}; bool UpperCommManager::processUpperMsg(const string& key, const string& strJson) { if(key == DB_TO_PM_MSCMD) { @@ -15,11 +15,29 @@ bool UpperCommManager::processUpperMsg(const string& key, const string& strJson) } else if(key == DB_TO_PM_EQUIPMENTCMD) { m_pm->m_MSDriverCmd = getEquipmentCmd(key, strJson); + vector devCmdExt = m_pm->m_driver.loadDriverIdFromJson(strJson); + if (devCmdExt.empty()) { + LOG_F(WARNING, "控制指令"); + } + else { + for (auto& cmd : devCmdExt) { + DevCmdExt event(cmd.id, cmd.cmd); + PowerManagerFsm::dispatch(event); + } + } return true; } - else if(key == DB_TO_PM_SUBDISSTATE) { - m_pm->m_subDisSysState = getSubDisState(key, strJson); - return true; + // else if(key == DB_TO_PM_SUBDISSTATE) { + // m_pm->m_subDisSysState = getSubDisState(key, strJson); + // return true; + // } + // 次级配电状态处理 + else if(key == m_secdistStateMsg.key_fb) { + m_secdistStateMsg.parseMsg(strJson, m_pm->m_subDisSysState); + //debug 接受到次级配电状态,自动更新到设备状态 + //TODO:自动更新到设备状态 + //m_pm->m_subDisSysState = m_pm->m_deviceState; + return true; } else if(key == DB_TO_PM_DEEPTH) { m_pm->m_depth = getDeepth(key, strJson); @@ -97,6 +115,7 @@ const DriverTable UpperCommManager::getEquipmentCmd(const std::string& key, cons if (m_pm->m_driver.loadDriverTableFromJson(msg, cmd) < 0) { cout << MOOS::ConsoleColours::Red << "get equipment cmd error:" << msg << MOOS::ConsoleColours::reset << endl; + LOG_F(WARNING, "get equipment cmd error:%s", msg.c_str()); } return cmd; } @@ -107,6 +126,7 @@ const DriverTable UpperCommManager::getSubDisState(const std::string& key, const if (m_pm->m_driver.loadDriverTableFromJson(msg, state) < 0) { cout << MOOS::ConsoleColours::Red << "get sub dis state error:" << msg << MOOS::ConsoleColours::reset << endl; + LOG_F(WARNING, "get sub dis state error:%s", msg.c_str()); } } @@ -120,21 +140,22 @@ const int UpperCommManager::getDeepth(const std::string& key, const std::string& std::istringstream stream(msg); if (!Json::parseFromStream(builder, stream, &root, &errs)) { std::cerr << "JSON解析失败: " << errs << std::endl; + LOG_F(WARNING, "JSON解析失败: %s", errs.c_str()); return -1; } // 检查并读取深度数组 - if (root.isMember("value_array_uint16") && root["value_array_uint16"].isArray()) { - const Json::Value& array = root["value_array_uint16"]; + if (root.isMember("value_array_int32") && root["value_array_int32"].isArray()) { + const Json::Value& array = root["value_array_int32"]; if (array.size() >= 3) { // 计算三个深度值的平均值 deepth = (array[0].asInt() + array[1].asInt() + array[2].asInt()) / 3; } else { - std::cerr << "深度数组元素不足3个" << std::endl; + LOG_F(WARNING, "深度数组元素不足3个"); return -1; } } else { - std::cerr << "JSON格式错误" << std::endl; + LOG_F(WARNING, "缺少或类型不匹配: value_array_int32"); return -1; } @@ -290,11 +311,6 @@ DeviceSwitchCmd UpperCommManager::getSetDevSwitch(const std::string& key, const } return false; } - - const std::string UpperCommManager::getCurrentEquState(DriverTable& driver) -{ - return m_pm->m_driver.saveDriverTableToJson(&driver); -} const std::string UpperCommManager::getSubDisCmd(DriverTable& driver) { @@ -304,10 +320,15 @@ const std::string UpperCommManager::getSubDisCmd(DriverTable& driver) void UpperCommManager::processPeriodicTasks() { buildSystemReport(); std::string strJson; - strJson = getCurrentEquState(m_pm->m_currentDriverState); - m_pm->sendNotification(PM_TO_DB_EQUIPMENTSTATE, strJson); - strJson = getSubDisCmd(m_pm->m_subDisSysCmd); - m_pm->sendNotification(PM_TO_DB_SUBDISCMD, strJson); + //发送当前设备状态 + strJson = m_equStateMsg.buildMsg(m_pm->m_currentDriverState); + m_pm->sendNotification(m_equStateMsg.key, strJson); + //发送次级配电指令 修改后的代码 + // strJson = getSubDisCmd(m_pm->m_subDisSysCmd); + strJson = m_secdistStateMsg.buildMsg(m_pm->m_subDisSysCmd); + m_pm->sendNotification(m_secdistStateMsg.key_cmd, strJson); + //发送仪表电状态 + m_pm->sendNotification(m_equInsStateMsg.key,m_equInsStateMsg.buildMsg(m_pm->m_subDisSysState)); } bool UpperCommManager::parseControlCmdFromJson(MSControlCmd &cmd, const std::string &strJson) { @@ -354,394 +375,21 @@ bool UpperCommManager::parseControlCmdFromJson(MSControlCmd &cmd, const std::str return true; // 成功 } void UpperCommManager::buildSystemReport() { - string suffix; - Json::Value pms; - Json::Value fcs; - Json::Value lbs; - Json::Value dis; - // 构建能源系统报告 - //1.构建系统状态报告 - suffix = getTypeName(typeid(m_pm->workCondition).name()); - pms[VAR_TO_STR(workCondition)+suffix] = m_pm->workCondition; - - suffix = getTypeName(typeid(m_pm->currentMod).name()); - pms[VAR_TO_STR(currentMod)+suffix] = m_pm->currentMod; - - suffix = getTypeName(typeid(m_pm->powerState).name()); - pms[VAR_TO_STR(powerState)+suffix] = m_pm->powerState; - - suffix = getTypeName(typeid(m_pm->faultLevel).name()); - pms[VAR_TO_STR(faultLevel)+suffix] = m_pm->faultLevel; - - Json::Value faultCode_array; - for(auto val : m_pm->faultCode) - { - faultCode_array.append(val); - } - pms[VAR_TO_STR(faultCode_array)] = faultCode_array; - - suffix = getTypeName(typeid(m_pm->soc).name()); - pms["soc_uint16"] = m_pm->soc; - - suffix = getTypeName(typeid(m_pm->sustainableTime).name()); - pms["sustainableTime_int64"] = m_pm->sustainableTime; - - pms["leakage_uint8"] = m_pm->m_leakage; - - //2.构建燃料电池状态报告 - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuState).name()); - fcs[VAR_TO_STR(fcuState)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuFaultLeve).name()); - fcs[VAR_TO_STR(fcuFaultLeve)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuFaultLeve; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerLimit).name()); - fcs[VAR_TO_STR(powLimit)+suffix] = m_pm->m_pmCurrentState.ccustate.powerLimit; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.totalPowerGeneration).name()); - fcs[VAR_TO_STR(powerGen)+suffix] = m_pm->m_pmCurrentState.ccustate.totalPowerGeneration; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.ch4o).name()); - fcs[VAR_TO_STR(ch4o)+suffix] = m_pm->m_pmCurrentState.ccustate.ch4o; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.o2).name()); - fcs[VAR_TO_STR(o2)+suffix] = m_pm->m_pmCurrentState.ccustate.o2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuVoltage).name()); - fcs[VAR_TO_STR(fcuVol)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuVoltage; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrent).name()); - fcs[VAR_TO_STR(fcuCur)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrent; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.o2Level).name()); - fcs[VAR_TO_STR(o2Level)+suffix] = m_pm->m_pmCurrentState.ccustate.o2Level; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.exchangerTemperature).name()); - fcs[VAR_TO_STR(excTemp)+suffix] = m_pm->m_pmCurrentState.ccustate.exchangerTemperature; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuOutPower).name()); - fcs[VAR_TO_STR(fcuOutPower)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuOutPower; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuOutIns).name()); - fcs[VAR_TO_STR(fcuOutIns)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuOutIns; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuVoltageIns).name()); - fcs[VAR_TO_STR(fcuVolIns)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuVoltageIns; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuVoltagePower).name()); - fcs[VAR_TO_STR(fcuVolPower)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuVoltagePower; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentIns).name()); - fcs[VAR_TO_STR(fcuCurIns)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentIns; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentPower).name()); - fcs[VAR_TO_STR(fcuCurPower)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentPower; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.h2Concentration1).name()); - fcs[VAR_TO_STR(h2Concent1)+suffix] = m_pm->m_pmCurrentState.ccustate.h2Concentration1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.h2Concentration2).name()); - fcs[VAR_TO_STR(h2Concent2)+suffix] = m_pm->m_pmCurrentState.ccustate.h2Concentration2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.o2Concentration1).name()); - fcs[VAR_TO_STR(o2Concent1)+suffix] = m_pm->m_pmCurrentState.ccustate.o2Concentration1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.o2Concentration2).name()); - fcs[VAR_TO_STR(o2Concent2)+suffix] = m_pm->m_pmCurrentState.ccustate.o2Concentration2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.ch4oConcentration1).name()); - fcs[VAR_TO_STR(ch4oConcent1)+suffix] = m_pm->m_pmCurrentState.ccustate.ch4oConcentration1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.ch4oConcentration2).name()); - fcs[VAR_TO_STR(ch4oConcent2)+suffix] = m_pm->m_pmCurrentState.ccustate.ch4oConcentration2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.backpressure1).name()); - fcs[VAR_TO_STR(backpressure1)+suffix] = m_pm->m_pmCurrentState.ccustate.backpressure1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.backpressure2).name()); - fcs[VAR_TO_STR(backpressure2)+suffix] = m_pm->m_pmCurrentState.ccustate.backpressure2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.flameDetection).name()); - fcs[VAR_TO_STR(flameDet)+suffix] = m_pm->m_pmCurrentState.ccustate.flameDetection; - - unsigned short faultCode1; - unsigned short faultCode2; - unsigned short faultCode3; - faultCode1 = (m_pm->m_pmCurrentState.ccustate.fcuGZ_1H << 8) | m_pm->m_pmCurrentState.ccustate.fcuGZ_1L; - faultCode2 = (m_pm->m_pmCurrentState.ccustate.fcuGZ_2H << 8) | m_pm->m_pmCurrentState.ccustate.fcuGZ_2L; - faultCode3 = (m_pm->m_pmCurrentState.ccustate.fcuGZ_3H << 8) | m_pm->m_pmCurrentState.ccustate.fcuGZ_3L; - - suffix = getTypeName(typeid(faultCode1).name()); - fcs[VAR_TO_STR(faultCode1)+suffix] = faultCode1; - suffix = getTypeName(typeid(faultCode2).name()); - fcs[VAR_TO_STR(faultCode2)+suffix] = faultCode2; - suffix = getTypeName(typeid(faultCode3).name()); - fcs[VAR_TO_STR(faultCode3)+suffix] = faultCode3; - - //4.构建动力锂电池状态报告 - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPosRelayState).name()); - lbs[VAR_TO_STR(insPosRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.insPosRelayState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insNegRelayState).name()); - lbs[VAR_TO_STR(insNegRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.insNegRelayState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPosRelayState).name()); - lbs[VAR_TO_STR(powPosRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPosRelayState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerNegRelayState).name()); - lbs[VAR_TO_STR(powNegRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerNegRelayState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatLimit).name()); - lbs[VAR_TO_STR(insBatLimit)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatLimit; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatLimit).name()); - lbs[VAR_TO_STR(powerBatLimit)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatLimit; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatSoc).name()); - lbs[VAR_TO_STR(insBatSoc)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatSoc; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatSoc).name()); - lbs[VAR_TO_STR(powBatSoc)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatSoc; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatTotalElectricity).name()); - lbs[VAR_TO_STR(insBatTotalElect)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatTotalElectricity; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatTotalElectricity).name()); - lbs[VAR_TO_STR(powBatTotalElect)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatTotalElectricity; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatCurrentElectricity).name()); - lbs[VAR_TO_STR(insBatCurElect)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatCurrentElectricity; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatCurrentElectricity).name()); - lbs[VAR_TO_STR(powBatCurElect)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatCurrentElectricity; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insChargeState).name()); - lbs[VAR_TO_STR(insChargeState)+suffix] = m_pm->m_pmCurrentState.ccustate.insChargeState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerChargeState).name()); - lbs[VAR_TO_STR(powChargeState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerChargeState; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insLinkVoltage).name()); - lbs[VAR_TO_STR(insLinkVol)+suffix] = m_pm->m_pmCurrentState.ccustate.insLinkVoltage; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPackVoltage).name()); - lbs[VAR_TO_STR(insPackVol)+suffix] = m_pm->m_pmCurrentState.ccustate.insPackVoltage; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrent).name()); - lbs[VAR_TO_STR(insCurrent)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrent; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPosInsulationResistance).name()); - lbs[VAR_TO_STR(insPosRes)+suffix] = m_pm->m_pmCurrentState.ccustate.insPosInsulationResistance; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insNegInsulationResistance).name()); - lbs[VAR_TO_STR(insNegRes)+suffix] = m_pm->m_pmCurrentState.ccustate.insNegInsulationResistance; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerLinkVoltage).name()); - lbs[VAR_TO_STR(powLinkVol)+suffix] = m_pm->m_pmCurrentState.ccustate.powerLinkVoltage; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPackVoltage).name()); - lbs[VAR_TO_STR(powerPackVol)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPackVoltage; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrent).name()); - lbs[VAR_TO_STR(powCur)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrent; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPosInsulationResistance).name()); - lbs[VAR_TO_STR(powPosRes)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPosInsulationResistance; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerNegInsulationResistance).name()); - lbs[VAR_TO_STR(powNegRes)+suffix] = m_pm->m_pmCurrentState.ccustate.powerNegInsulationResistance; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold1).name()); - lbs[VAR_TO_STR(insCurSocHold1)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold2).name()); - lbs[VAR_TO_STR(insCurSocHold2)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold3).name()); - lbs[VAR_TO_STR(insCurSocHold3)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold3; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentToInsLimit1).name()); - lbs[VAR_TO_STR(fcuCurToInsLimit1)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentToInsLimit1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentToinsLimit2).name()); - lbs[VAR_TO_STR(fcuCurToinsLimit2)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentToinsLimit2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold1).name()); - lbs[VAR_TO_STR(powCurSocHold1)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold2).name()); - lbs[VAR_TO_STR(powCurSocHold2)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold3).name()); - lbs[VAR_TO_STR(powCurSocHold3)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold3; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentToInsLimit1).name()); - lbs[VAR_TO_STR(powCurToInsLimit1)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentToInsLimit1; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentToinsLimit2).name()); - lbs[VAR_TO_STR(powCurToinsLimit2)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentToinsLimit2; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insAlarmIdentificationWord).name()); - lbs[VAR_TO_STR(insfaultCode)+suffix] = m_pm->m_pmCurrentState.ccustate.insAlarmIdentificationWord; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerAlarmIdentificationWord).name()); - lbs[VAR_TO_STR(powfaultCode)+suffix] = m_pm->m_pmCurrentState.ccustate.powerAlarmIdentificationWord; - - //5.构建配电系统状态报告 - disBus1Breaker* pdis1=new disBus1Breaker; - disBus2Breaker* pdis2=new disBus2Breaker; - disBus3Breaker* pdis3=new disBus3Breaker; - disBus4Breaker* pdis4=new disBus4Breaker; - - *pdis1 = m_pm->m_currentDisBreakerState.bus1Breaker; - *pdis2 = m_pm->m_currentDisBreakerState.bus2Breaker; - *pdis3 = m_pm->m_currentDisBreakerState.bus3Breaker; - *pdis4 = m_pm->m_currentDisBreakerState.bus4Breaker; - - dis["HVolBusBreaker_uint16"] = *(unsigned short*)pdis1; - dis["HVolABusBreaker_unit16"] = *(unsigned short*)pdis2; - dis["HVolBBusBreaker_unit16"] = *(unsigned short*)pdis3; - dis["LVolBusBreaker_uint16"] = *(unsigned short*)pdis4; - - //TODO: 构建配电系统故障码 - Json::Value faultCodeDis_array; - for(auto val : m_pm->faultCode) - { - faultCodeDis_array.append(val); - } - dis[VAR_TO_STR(faultCode_array)] = faultCodeDis_array; - - - Json::Value currentBusState; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.powerBusVoltage).name()); - currentBusState[VAR_TO_STR(HVBpowerBusVol)+suffix] = m_pm->m_pmCurrentState.bus1State.powerBusVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCurrent).name()); - currentBusState[VAR_TO_STR(HVBdcDc5Cur)+suffix] = m_pm->m_pmCurrentState.bus1State.dcDc5ModuleCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.powerBusCurrent).name()); - currentBusState[VAR_TO_STR(HVBpowerBusCur)+suffix] = m_pm->m_pmCurrentState.bus1State.powerBusCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.busbarAVoltage).name()); - currentBusState[VAR_TO_STR(HVBbusAVol)+suffix] = m_pm->m_pmCurrentState.bus1State.busbarAVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.propulsionMotorControlBoxCurrent).name()); - currentBusState[VAR_TO_STR(HVBmotorCur)+suffix] = m_pm->m_pmCurrentState.bus1State.propulsionMotorControlBoxCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.busbarACurrent).name()); - currentBusState[VAR_TO_STR(HVBbusACur)+suffix] = m_pm->m_pmCurrentState.bus1State.busbarACurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupMeterCurrent).name()); - currentBusState[VAR_TO_STR(HVBbatGroupCur)+suffix] = m_pm->m_pmCurrentState.bus1State.lithiumBatteryGroupMeterCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCurrent).name()); - currentBusState[VAR_TO_STR(HVBbowHVolDisBoxCur)+suffix] = m_pm->m_pmCurrentState.bus1State.bowHighVoltageDistributionBoxCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.sternFTDevice45Current).name()); - currentBusState[VAR_TO_STR(HVBFTDev45Cur)+suffix] = m_pm->m_pmCurrentState.bus1State.sternFTDevice45Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.tyzReservedSwitchCurrent).name()); - currentBusState[VAR_TO_STR(HVBtyzCur)+suffix] = m_pm->m_pmCurrentState.bus1State.tyzReservedSwitchCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1Current).name()); - currentBusState[VAR_TO_STR(HVBsternRud1Cur)+suffix] = m_pm->m_pmCurrentState.bus1State.sternRudderSwitch1Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.reservedCurrent1).name()); - currentBusState[VAR_TO_STR(HVBreservedCur1)+suffix] = m_pm->m_pmCurrentState.bus1State.reservedCurrent1; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2Current).name()); - currentBusState[VAR_TO_STR(HVBsternRud2Cur)+suffix] = m_pm->m_pmCurrentState.bus1State.sternRudderSwitch2Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.reservedCurrent2).name()); - currentBusState[VAR_TO_STR(HVBreservedCur2)+suffix] = m_pm->m_pmCurrentState.bus1State.reservedCurrent2; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.fbReservedSwitchCurrent).name()); - currentBusState[VAR_TO_STR(HVBfbCur)+suffix] = m_pm->m_pmCurrentState.bus1State.fbReservedSwitchCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus1State.reservedCurrent3).name()); - currentBusState[VAR_TO_STR(HVBreservedCur3)+suffix] = m_pm->m_pmCurrentState.bus1State.reservedCurrent3; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.busbarBVoltage).name()); - currentBusState[VAR_TO_STR(HVABbusBVol)+suffix] = m_pm->m_pmCurrentState.bus2State.busbarBVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.busbarBCurrent).name()); - currentBusState[VAR_TO_STR(HVABbusBCur)+suffix] = m_pm->m_pmCurrentState.bus2State.busbarBCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.bowFTDevice123Current).name()); - currentBusState[VAR_TO_STR(HVABFTDev123Cur)+suffix] = m_pm->m_pmCurrentState.bus2State.bowFTDevice123Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.actuatorCurrent).name()); - currentBusState[VAR_TO_STR(HVABactCur)+suffix] = m_pm->m_pmCurrentState.bus2State.actuatorCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCurrent).name()); - currentBusState[VAR_TO_STR(HVABmastSteGeaCur)+suffix] = m_pm->m_pmCurrentState.bus2State.mastSteeringGearControlBoxCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.xczCurrent).name()); - currentBusState[VAR_TO_STR(HVABxczCur)+suffix] = m_pm->m_pmCurrentState.bus2State.xczCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCurrent).name()); - currentBusState[VAR_TO_STR(HVABbowRudCur)+suffix] = m_pm->m_pmCurrentState.bus2State.bowRudderControlBoxCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCurrent).name()); - currentBusState[VAR_TO_STR(HVABopenWaterCur)+suffix] = m_pm->m_pmCurrentState.bus2State.openWaterCoverStartCylinderCurrent; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.instrumentBusbarVoltage).name()); - currentBusState[VAR_TO_STR(HVBBinsBusVol)+suffix] = m_pm->m_pmCurrentState.bus3State.instrumentBusbarVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCurrent).name()); - currentBusState[VAR_TO_STR(HVBBbowLowVolDisBoxCur)+suffix] = m_pm->m_pmCurrentState.bus3State.bowLowVoltageDistributionBoxCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.dcC1InstrumentDC48VCurrent).name()); - currentBusState[VAR_TO_STR(HVBBdcC1InsCur)+suffix] = m_pm->m_pmCurrentState.bus3State.dcC1InstrumentDC48VCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.reservedCurrent1).name()); - currentBusState[VAR_TO_STR(HVBBreservedCur1)+suffix] = m_pm->m_pmCurrentState.bus3State.reservedCurrent1; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2Current).name()); - currentBusState[VAR_TO_STR(HVBBemerBatCur)+suffix] = m_pm->m_pmCurrentState.bus3State.emergencyLithiumBatteryGroup2Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCurrent).name()); - currentBusState[VAR_TO_STR(HVBBbatInsCur)+suffix] = m_pm->m_pmCurrentState.bus3State.lithiumBatteryGroupInstrumentCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCurrent).name()); - currentBusState[VAR_TO_STR(HVBBunit4Cur)+suffix] = m_pm->m_pmCurrentState.bus3State.unit4InstrumentDC48VCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.reservedCurrent2).name()); - currentBusState[VAR_TO_STR(HVBBreservedCur2)+suffix] = m_pm->m_pmCurrentState.bus3State.reservedCurrent2; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.emergency2BusbarVoltage).name()); - currentBusState[VAR_TO_STR(HVBBemer2BusVol)+suffix] = m_pm->m_pmCurrentState.bus3State.emergency2BusbarVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.compositeEnergyManagementSystemEmergencyDC48VCurrent).name()); - currentBusState[VAR_TO_STR(HVBBCCUCur)+suffix] = m_pm->m_pmCurrentState.bus3State.compositeEnergyManagementSystemEmergencyDC48VCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.fuelCellSecuritySystemEmergencyDC48VCurrent).name()); - currentBusState[VAR_TO_STR(HVBBFCSSecurSysCur)+suffix] = m_pm->m_pmCurrentState.bus3State.fuelCellSecuritySystemEmergencyDC48VCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus3State.plcControlPowerCurrent).name()); - currentBusState[VAR_TO_STR(HVBBplcCur)+suffix] = m_pm->m_pmCurrentState.bus3State.plcControlPowerCurrent; - - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.instrumentBusbarVoltage).name()); - currentBusState[VAR_TO_STR(LVBinsBusVol)+suffix] = m_pm->m_pmCurrentState.bus4State.instrumentBusbarVoltage; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.instrumentBusbarCurrent).name()); - currentBusState[VAR_TO_STR(LVBBinsBusCur)+suffix] = m_pm->m_pmCurrentState.bus4State.instrumentBusbarCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.unit1Current).name()); - currentBusState[VAR_TO_STR(LVBBunit1Cur)+suffix] = m_pm->m_pmCurrentState.bus4State.unit1Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.unit2Current).name()); - currentBusState[VAR_TO_STR(LVBBunit2Cur)+suffix] = m_pm->m_pmCurrentState.bus4State.unit2Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.unit3Current).name()); - currentBusState[VAR_TO_STR(LVBBunit3Cur)+suffix] = m_pm->m_pmCurrentState.bus4State.unit3Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.unit5Current).name()); - currentBusState[VAR_TO_STR(LVBBunit5Cur)+suffix] = m_pm->m_pmCurrentState.bus4State.unit5Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.bowPZDeviceCurrent).name()); - currentBusState[VAR_TO_STR(LVBBbowPZDevCur)+suffix] = m_pm->m_pmCurrentState.bus4State.bowPZDeviceCurrent; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1Current).name()); - currentBusState[VAR_TO_STR(LVBBemerBatCur)+suffix] = m_pm->m_pmCurrentState.bus4State.emergencyLithiumBatteryGroup1Current; - suffix = getTypeName(typeid(m_pm->m_pmCurrentState.bus4State.emergency1BusbarVoltage).name()); - currentBusState[VAR_TO_STR(LVBBemerBusVol)+suffix] = m_pm->m_pmCurrentState.bus4State.emergency1BusbarVoltage; - - // dis["currentBusState"] = currentBusState; - - // pms[VAR_TO_STR(fcs_obj)] = fcs; - // pms[VAR_TO_STR(lbs_obj)] = lbs; - // pms[VAR_TO_STR(dis_obj)] = dis; - - m_pm->sendNotification(PM_TO_DB_STATE, pms.toStyledString()); - m_pm->sendNotification(PM_TO_DB_FCSSTATE, fcs.toStyledString()); - m_pm->sendNotification(PM_TO_DB_LIBATSTATE, lbs.toStyledString()); - m_pm->sendNotification(PM_TO_DB_DISSTATE, dis.toStyledString()); - m_pm->sendNotification(PM_TO_DB_CURRENTSTATE, currentBusState.toStyledString()); - - // 使用StreamWriterBuilder来设置保持插入顺序 - Json::StreamWriterBuilder builder; - builder["indentation"] = " "; // 设置不缩进,保持紧凑格式 - builder["enableYAMLCompatibility"] = true; // 保持插入顺序 - - // 将Json::Value对象转换为字符串 - string pathFile = "/home/zjk/project/H100/H100PowerManger/data/msg/"; - string jsonStr = Json::writeString(builder, pms); - - saveStringToJsonFile(jsonStr, pathFile+PM_TO_DB_STATE+".json"); - - jsonStr = Json::writeString(builder, fcs); - saveStringToJsonFile(jsonStr, pathFile+PM_TO_DB_FCSSTATE+".json"); - - jsonStr = Json::writeString(builder, lbs); - saveStringToJsonFile(jsonStr, pathFile+PM_TO_DB_LIBATSTATE+".json"); - - jsonStr = Json::writeString(builder, dis); - saveStringToJsonFile(jsonStr, pathFile+PM_TO_DB_DISSTATE + ".json"); - - jsonStr = Json::writeString(builder, currentBusState); - saveStringToJsonFile(jsonStr, pathFile+PM_TO_DB_CURRENTSTATE + ".json"); - -// return true; + m_pmStateMsg.state.workCondition = m_pm->workCondition; + m_pmStateMsg.state.currentMod = m_pm->currentMod; + m_pmStateMsg.state.powerState = m_pm->powerState; + m_pmStateMsg.state.faultLevel = m_pm->faultLevel; + m_pmStateMsg.state.faultCode = m_pm->faultCode; + m_pmStateMsg.state.soc = m_pm->soc; + m_pmStateMsg.state.sustainableTime = m_pm->sustainableTime; + m_pmStateMsg.state.m_leakage = m_pm->m_leakage; + m_pmStateMsg.state.m_faultNum = m_pm->m_faultNum; + + m_pm->sendNotification(m_pmStateMsg.key, m_pmStateMsg.buildMsg()); + m_pm->sendNotification(m_fcsStateMsg.key, m_fcsStateMsg.buildMsg(m_pm->m_pmCurrentState.ccustate)); + m_pm->sendNotification(m_liBatStateMsg.key, m_liBatStateMsg.buildMsg(m_pm->m_pmCurrentState.ccustate)); + m_pm->sendNotification(m_disSysStateMsg.key, m_disSysStateMsg.buildMsg(m_pm->m_currentDisBreakerState)); + m_pm->sendNotification(m_currentStateMsg.key, m_currentStateMsg.buildMsg(m_pm->m_pmCurrentState)); } bool UpperCommManager::saveStringToJsonFile(const string &strJson, const string &filePath) { @@ -755,36 +403,4 @@ bool UpperCommManager::saveStringToJsonFile(const string &strJson, const string std::cerr << "无法打开文件!" << std::endl; return false; } -} -string UpperCommManager::getTypeName(const string typeName) -{ - // 映射类型名称到指定的字符串 - if (typeName == "i" || typeName == "c") { - return "_int8"; - } else if (typeName == "h" || typeName == "C") { - return "_uint8"; - } else if (typeName == "s" || typeName == "S") { - return "_int16"; - } else if (typeName == "t" || typeName == "T") { - return "_uint16"; - } else if (typeName == "i" || typeName == "I") { - return "_int32"; - } else if (typeName == "j" || typeName == "J") { - return "_uint32"; - } else if (typeName == "x" || typeName == "X") { - return "_int64"; - } else if (typeName == "f" || typeName == "F") { - return "_fp32"; - } else if (typeName == "d" || typeName == "D") { - return "_fp64"; - } else if (typeName == "b" || typeName == "B") { - return "_bool"; - } else if (typeName == "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE") { - return "_str"; - } else if (typeName == "St6vector" || typeName == "St5deque" || typeName == "St4list" || typeName == "St4pair") { - return "_array"; - } else { - // 默认情况 - return "_obj"; - } } \ No newline at end of file diff --git a/src/pPowerManger/UpperCommManager.h b/src/pPowerManger/UpperCommManager.h index ea8216f..50cef95 100644 --- a/src/pPowerManger/UpperCommManager.h +++ b/src/pPowerManger/UpperCommManager.h @@ -8,6 +8,14 @@ #include #include #include +#include "msg/uPower_equInsState.h" +#include "msg/uDevice_secdistState.h" +#include "msg/uPower_equState.h" +#include "msg/uPower_disSysState.h" +#include "msg/uPower_currentState_st.h" +#include "msg/uPower_pmState.h" +#include "msg/uPower_fcsState.h" +#include "msg/uPower_liBatState.h" using namespace std; #define VAR_TO_STR(var) #var //能源管理反馈的消息 @@ -18,7 +26,6 @@ using namespace std; #define PM_TO_DB_FCSSTATE "uPower_fcsState_st" #define PM_TO_DB_SUBDISCMD "uPower_secdistState_cmd" -#define PM_TO_DB_EQUIPMENTSTATE "uPower_equState_fb" //控制消息 #define DB_TO_PM_MSCMD "uPower_sysState_cmd" @@ -65,19 +72,25 @@ public: int getSetPMSys(const std::string& key, const std::string& msg); DeviceSwitchCmd getSetDevSwitch(const std::string& key, const std::string& msg); - const std::string getCurrentEquState(DriverTable& driver); const std::string getSubDisCmd(DriverTable& driver); // 其他公共函数 - string getTypeName(const string typeName); bool saveStringToJsonFile(const string &strJson, const string &filePath); - private: PowerManger* m_pm; MSControlCmd m_msCmd; Driver m_driver; + //定义上位机消息 + uPower_equInsStateMsg m_equInsStateMsg; + uDevice_secdistStateMsg m_secdistStateMsg; + uPower_equStateMsg m_equStateMsg; + uPower_disSysStateMsg m_disSysStateMsg; + uPower_currentStateMsg m_currentStateMsg; + uPower_pmStateMsg m_pmStateMsg; + uPower_fcsStateMsg m_fcsStateMsg; + uPower_liBatStateMsg m_liBatStateMsg; + - // 从JSON解析控制命令 bool parseControlCmdFromJson(MSControlCmd &cmd, const std::string &strJson); }; diff --git a/src/pPowerManger/ccuUdpMsg.h b/src/pPowerManger/ccuUdpMsg.h index f4af522..d7e736a 100644 --- a/src/pPowerManger/ccuUdpMsg.h +++ b/src/pPowerManger/ccuUdpMsg.h @@ -8,9 +8,9 @@ #define DIS_MSG_HEAD1 0x40 #define DIS_MSG_HEAD2 0x40 -#define CCU_CMD_ID 0x0050 -#define CCU_SET_PARM_ID 0x0051 -#define CCU_STATE_FB_ID 0x0041 +#define CCU_CMD_ID 0x0040 +#define CCU_SET_PARM_ID 0x0041 +#define CCU_STATE_FB_ID 0x0051 #define CCU_SET_PARM_FB_ID 0x0040 #define DIS_HVBUS_FB_ID 0x0005 diff --git a/src/pPowerManger/driver.cpp b/src/pPowerManger/driver.cpp index 5bfddec..cd0dd78 100644 --- a/src/pPowerManger/driver.cpp +++ b/src/pPowerManger/driver.cpp @@ -763,210 +763,264 @@ int Driver::SafeReadUInt(const Json::Value& root, const std::string& key, unsign return 0; // 成功读取 } +vector Driver::loadDriverIdFromJson(const std::string &strJson) { + Json::CharReaderBuilder builder; + Json::Value root; + std::string errs; + vector driverCmd; + + // 解析JSON字符串 + std::istringstream s(strJson); + if (!Json::parseFromStream(builder, s, &root, &errs)) { + std::cerr << "JSON解析失败: " << errs << std::endl; + return driverCmd; + } + // 设备字段名到ID的映射 + const std::map fieldToId = { + {"depth1", 18}, {"depth2", 19}, {"depth3", 20}, + {"overDeep1", 21}, {"overDeep2", 22}, + {"ctd1", 23}, {"ctd2", 24}, {"soundVeloc", 25}, + {"commMast", 40}, {"ins", 57}, {"ntp", 58}, + {"inputWaterSensor1", 59}, {"inputWaterSensor2", 60}, {"inputWaterSensor3", 61}, + {"singleBeamSonar1", 0}, {"singleBeamSonar2", 1}, {"singleBeamSonar3", 2}, + {"singleBeamSonar4", 3}, {"singleBeamSonar5", 4}, {"singleBeamSonar6", 5}, + {"singleBeamSonar7", 6}, {"singleBeamSonar8", 7}, {"forwardSonar", 8}, + {"DVL", 43}, {"lowFreqSonar", 36}, {"USBL", 42}, + {"bowCover1", 9}, {"bowCover2", 10}, {"bowCover3", 11}, + {"bowCover4", 12}, {"bowCover5", 13}, {"bowCover6", 14}, + {"bowRudderDeploy", 15}, {"bowRudderServo1", 16}, {"bowRudderServo2", 17}, + {"bowWaterlnet1", 27}, {"bowWaterlnet2", 28}, {"bowWaterlnet3", 29}, + {"bowWaterlnet4", 30}, {"bowWaterlnet5", 31}, {"bowWaterlnet6", 32}, + {"bowWaterlnet7", 33}, {"bowWaterlnet8", 34}, {"waterInject", 26}, + {"mastLiftingServo", 41}, {"buoyancyAdjust1", 44}, {"buoyancyAdjust2", 45}, + {"buoyancyAdjust3", 46}, {"buoyancyAdjust4", 47}, {"buoyancyAdjust5", 48}, + {"sternRudderServo1", 49}, {"sternRudderServo2", 50}, {"sternRudderServo3", 51}, + {"sternRudderServo4", 52}, {"thruster", 53}, {"bowThrow", 54}, + {"sternThrow", 55}, {"photoSensor", 38}, {"electSensor", 39}, + {"launchControler", 37}, {"sideSonar", 35}, {"buoyage", 56} + }; + + // 检查每个字段,如果存在且值发生变化,则添加到返回向量中 + for (const auto& [field, id] : fieldToId) { + if (root.isMember(field)) { + unsigned char newValue = root[field].asUInt(); + // unsigned char& currentValue = *((unsigned char*)&table + offsetof(DriverTable, depth1) + + // (fieldToId.at(field) - 18) * sizeof(unsigned char)); + + DriverCommand cmd; + cmd.id = id; + cmd.cmd = newValue; + driverCmd.push_back(cmd); + } + } + + return driverCmd; +} + int Driver::loadDriverTableFromJson(const std::string &strJson, DriverTable& table) { Json::CharReaderBuilder builder; Json::Value root; std::string errs; - + // 解析JSON字符串 std::istringstream s(strJson); if (!Json::parseFromStream(builder, s, &root, &errs)) { std::cerr << "JSON解析失败: " << errs << std::endl; return -3; // 解析失败 + } - // 读取 JSON 数据并填充结构体,逐个字段检查 int error_code = 0; - error_code = SafeReadUInt(root, "depth1", table.depth1); + error_code = SafeReadUInt(root, "depth1_uint8", table.depth1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "depth2", table.depth2); + error_code = SafeReadUInt(root, "depth2_uint8", table.depth2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "depth3", table.depth3); + error_code = SafeReadUInt(root, "depth3_uint8", table.depth3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "overDeep1", table.overDeep1); + // error_code = SafeReadUInt(root, "overDeep1_uint8", table.overDeep1); + // if (error_code != 0) return error_code; + + // error_code = SafeReadUInt(root, "overDeep2_uint8", table.overDeep2); + // if (error_code != 0) return error_code; + + error_code = SafeReadUInt(root, "ctd1_uint8", table.ctd1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "overDeep2", table.overDeep2); + error_code = SafeReadUInt(root, "ctd2_uint8", table.ctd2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "ctd1", table.ctd1); + error_code = SafeReadUInt(root, "soundVeloc_uint8", table.soundVeloc); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "ctd2", table.ctd2); + error_code = SafeReadUInt(root, "commDev_uint8", table.commMast); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "soundVeloc", table.soundVeloc); + error_code = SafeReadUInt(root, "ins_uint8", table.ins); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "commMast", table.commMast); + error_code = SafeReadUInt(root, "ntp_uint8", table.ntp); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "ins", table.ins); + error_code = SafeReadUInt(root, "inputWaterSensor1_uint8", table.inputWaterSensor1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "ntp", table.ntp); + error_code = SafeReadUInt(root, "inputWaterSensor2_uint8", table.inputWaterSensor2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "inputWaterSensor1", table.inputWaterSensor1); - if (error_code != 0) return error_code; - - error_code = SafeReadUInt(root, "inputWaterSensor2", table.inputWaterSensor2); - if (error_code != 0) return error_code; - - error_code = SafeReadUInt(root, "inputWaterSensor3", table.inputWaterSensor3); + error_code = SafeReadUInt(root, "inputWaterSensor3_uint8", table.inputWaterSensor3); if (error_code != 0) return error_code; // 水声设备 - error_code = SafeReadUInt(root, "singleBeamSonar1", table.singleBeamSonar1); + error_code = SafeReadUInt(root, "singleBeamSonar1_uint8", table.singleBeamSonar1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar2", table.singleBeamSonar2); + error_code = SafeReadUInt(root, "singleBeamSonar2_uint8", table.singleBeamSonar2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar3", table.singleBeamSonar3); + error_code = SafeReadUInt(root, "singleBeamSonar3_uint8", table.singleBeamSonar3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar4", table.singleBeamSonar4); + error_code = SafeReadUInt(root, "singleBeamSonar4_uint8", table.singleBeamSonar4); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar5", table.singleBeamSonar5); + error_code = SafeReadUInt(root, "singleBeamSonar5_uint8", table.singleBeamSonar5); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar6", table.singleBeamSonar6); + error_code = SafeReadUInt(root, "singleBeamSonar6_uint8", table.singleBeamSonar6); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar7", table.singleBeamSonar7); + error_code = SafeReadUInt(root, "singleBeamSonar7_uint8", table.singleBeamSonar7); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "singleBeamSonar8", table.singleBeamSonar8); + error_code = SafeReadUInt(root, "singleBeamSonar8_uint8", table.singleBeamSonar8); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "forwardSonar", table.forwardSonar); + error_code = SafeReadUInt(root, "forwardSonar_uint8", table.forwardSonar); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "DVL", table.DVL); + error_code = SafeReadUInt(root, "DVL_uint8", table.DVL); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "lowFreqSonar", table.lowFreqSonar); + error_code = SafeReadUInt(root, "lowFreqSonar_uint8", table.lowFreqSonar); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "USBL", table.USBL); + error_code = SafeReadUInt(root, "USBL_uint8", table.USBL); if (error_code != 0) return error_code; // 执行机构 - error_code = SafeReadUInt(root, "bowWaterlnet1", table.bowWaterlnet1); + error_code = SafeReadUInt(root, "bowWaterlnet1_uint8", table.bowWaterlnet1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet2", table.bowWaterlnet2); + error_code = SafeReadUInt(root, "bowWaterlnet2_uint8", table.bowWaterlnet2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet3", table.bowWaterlnet3); + error_code = SafeReadUInt(root, "bowWaterlnet3_uint8", table.bowWaterlnet3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet4", table.bowWaterlnet4); + error_code = SafeReadUInt(root, "bowWaterlnet4_uint8", table.bowWaterlnet4); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet5", table.bowWaterlnet5); + error_code = SafeReadUInt(root, "bowWaterlnet5_uint8", table.bowWaterlnet5); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet6", table.bowWaterlnet6); + error_code = SafeReadUInt(root, "bowWaterlnet6_uint8", table.bowWaterlnet6); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet7", table.bowWaterlnet7); + error_code = SafeReadUInt(root, "bowWaterlnet7_uint8", table.bowWaterlnet7); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowWaterlnet8", table.bowWaterlnet8); + error_code = SafeReadUInt(root, "bowWaterlnet8_uint8", table.bowWaterlnet8); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowRudderDeploy", table.bowRudderDeploy); + error_code = SafeReadUInt(root, "bowRudderDeploy_uint8", table.bowRudderDeploy); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowRudderServo1", table.bowRudderServo1); + error_code = SafeReadUInt(root, "bowRudderServo1_uint8", table.bowRudderServo1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowRudderServo2", table.bowRudderServo2); + error_code = SafeReadUInt(root, "bowRudderServo2_uint8", table.bowRudderServo2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover1", table.bowCover1); + error_code = SafeReadUInt(root, "bowCover1_uint8", table.bowCover1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover2", table.bowCover2); + error_code = SafeReadUInt(root, "bowCover2_uint8", table.bowCover2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover3", table.bowCover3); + error_code = SafeReadUInt(root, "bowCover3_uint8", table.bowCover3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover4", table.bowCover4); + error_code = SafeReadUInt(root, "bowCover4_uint8", table.bowCover4); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover5", table.bowCover5); + error_code = SafeReadUInt(root, "bowCover5_uint8", table.bowCover5); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowCover6", table.bowCover6); + error_code = SafeReadUInt(root, "bowCover6_uint8", table.bowCover6); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "waterInject", table.waterInject); + error_code = SafeReadUInt(root, "waterInject_uint8", table.waterInject); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "mastLiftingServo", table.mastLiftingServo); + error_code = SafeReadUInt(root, "mastLiftingServo_uint8", table.mastLiftingServo); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyancyAdjust1", table.buoyancyAdjust1); + error_code = SafeReadUInt(root, "buoyancyAdjust1_uint8", table.buoyancyAdjust1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyancyAdjust2", table.buoyancyAdjust2); + error_code = SafeReadUInt(root, "buoyancyAdjust2_uint8", table.buoyancyAdjust2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyancyAdjust3", table.buoyancyAdjust3); + error_code = SafeReadUInt(root, "buoyancyAdjust3_uint8", table.buoyancyAdjust3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyancyAdjust4", table.buoyancyAdjust4); + error_code = SafeReadUInt(root, "buoyancyAdjust4_uint8", table.buoyancyAdjust4); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyancyAdjust5", table.buoyancyAdjust5); + error_code = SafeReadUInt(root, "buoyancyAdjust5_uint8", table.buoyancyAdjust5); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sternRudderServo1", table.sternRudderServo1); + error_code = SafeReadUInt(root, "sternRudderServo1_uint8", table.sternRudderServo1); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sternRudderServo2", table.sternRudderServo2); + error_code = SafeReadUInt(root, "sternRudderServo2_uint8", table.sternRudderServo2); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sternRudderServo3", table.sternRudderServo3); + error_code = SafeReadUInt(root, "sternRudderServo3_uint8", table.sternRudderServo3); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sternRudderServo4", table.sternRudderServo4); + error_code = SafeReadUInt(root, "sternRudderServo4_uint8", table.sternRudderServo4); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "thruster", table.thruster); + error_code = SafeReadUInt(root, "thruster_uint8", table.thruster); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "bowThrow", table.bowThrow); + error_code = SafeReadUInt(root, "bowThrow_uint8", table.bowThrow); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sternThrow", table.sternThrow); + error_code = SafeReadUInt(root, "sternThrow_uint8", table.sternThrow); if (error_code != 0) return error_code; // 负载 - error_code = SafeReadUInt(root, "photoSensor", table.photoSensor); + error_code = SafeReadUInt(root, "photoSensor_uint8", table.photoSensor); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "electSensor", table.electSensor); + error_code = SafeReadUInt(root, "electSensor_uint8", table.electSensor); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "launchControler", table.launchControler); + error_code = SafeReadUInt(root, "launchControler_uint8", table.launchControler); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "sideSonar", table.sideSonar); + error_code = SafeReadUInt(root, "sideSonar_uint8", table.sideSonar); if (error_code != 0) return error_code; - error_code = SafeReadUInt(root, "buoyage", table.buoyage); + error_code = SafeReadUInt(root, "buoyage_uint8", table.buoyage); if (error_code != 0) return error_code; return 0; // 返回0表示所有数据成功读取 diff --git a/src/pPowerManger/driver.h b/src/pPowerManger/driver.h index c30d7c7..eb01b65 100644 --- a/src/pPowerManger/driver.h +++ b/src/pPowerManger/driver.h @@ -3,7 +3,7 @@ #include "json/json.h" #include "iostream" #include - +#include #define DRIVER_POWER_OFF 0x00 #define DRIVER_FULL_POWER_ON 0x01 @@ -11,6 +11,7 @@ #define DRIVER_MOTIVE_POWER_ON 0x03 #define DRIVER_STANDBY 0x04 +using namespace std; struct DriverTable { unsigned char depth1; @@ -80,6 +81,13 @@ struct DriverTable unsigned char buoyage; }; +struct DriverCommand +{ + int id; + int cmd; +}; + + class Driver { public: @@ -115,6 +123,7 @@ public: std::string saveDriverTableToJson(const DriverTable* driverTable); int loadDriverTableFromJson(const std::string &strJson, DriverTable& table); + vector loadDriverIdFromJson(const std::string &strJson); int SafeReadUInt(const Json::Value& root, const std::string& key, unsigned char& value); diff --git a/src/pPowerManger/fsm/CruiseMode.cpp b/src/pPowerManger/fsm/CruiseMode.cpp new file mode 100644 index 0000000..2c2c65a --- /dev/null +++ b/src/pPowerManger/fsm/CruiseMode.cpp @@ -0,0 +1,20 @@ +#include "PowerManagerFsm.hpp" + +void CruiseMode::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::CHANING; + pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); + //依次接入执行机构动力电设备 + //TODO:接入执行机构动力电设备 + + //TODO:解除非必要动力电设备 + pm->workCondition = WorkCondition::CRUISE_MODE; + LOG_F(INFO, "进入巡航模式"); +} + +// CruiseMode实现 +void CruiseMode::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} diff --git a/src/pPowerManger/fsm/DJMode.cpp b/src/pPowerManger/fsm/DJMode.cpp new file mode 100644 index 0000000..7e0a41d --- /dev/null +++ b/src/pPowerManger/fsm/DJMode.cpp @@ -0,0 +1,15 @@ +#include "PowerManagerFsm.hpp" + + +// DJMode实现 +void DJMode::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + +void DJMode::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::DJ_MODE; + LOG_F(INFO, "进入DJ模式"); +} diff --git a/src/pPowerManger/fsm/FaultState.cpp b/src/pPowerManger/fsm/FaultState.cpp new file mode 100644 index 0000000..f8328d7 --- /dev/null +++ b/src/pPowerManger/fsm/FaultState.cpp @@ -0,0 +1,19 @@ +#include "PowerManagerFsm.hpp" + +// FaultState实现 +void FaultState::entry() { + PowerManagerFsm::entry(); + // PowerManagerFsm::pm->printState("FaultState", "进入故障状态"); + if(pm->m_missionState.type == TaskType::THROW_LOAD) + { + LOG_F(INFO, "检测到抛载,所有水声探测设备"); + } + else + { + // LOG_F(INFO, "检测到抛载,所有水声设备关闭"); + } +} + +void FaultState::react(FaultEvent const & e) { + LOG_F(INFO, "FaultState 处理故障事件"); +} diff --git a/src/pPowerManger/fsm/FloatAdjust.cpp b/src/pPowerManger/fsm/FloatAdjust.cpp new file mode 100644 index 0000000..259c323 --- /dev/null +++ b/src/pPowerManger/fsm/FloatAdjust.cpp @@ -0,0 +1,21 @@ +#include "PowerManagerFsm.hpp" + +// FloatAdjust实现 +void FloatAdjust::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + +void FloatAdjust::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::CHANING; + //与巡航模式相同 + pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); + //依次接入执行机构动力电设备 + //TODO:接入执行机构动力电设备 + + //TODO:解除非必要动力电设备 + pm->workCondition = WorkCondition::BUOYANCY_ADJUST; + LOG_F(INFO, "进入浮调模式"); +} diff --git a/src/pPowerManger/fsm/FloatDown.cpp b/src/pPowerManger/fsm/FloatDown.cpp new file mode 100644 index 0000000..973ec8a --- /dev/null +++ b/src/pPowerManger/fsm/FloatDown.cpp @@ -0,0 +1,20 @@ +#include "PowerManagerFsm.hpp" + +void FloatDown::entry() { + PowerManagerFsm::entry(); + //与巡航模式相同 + pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); + //依次接入执行机构动力电设备 + //TODO:接入执行机构动力电设备 + + //TODO:解除非必要动力电设备 + pm->workCondition = WorkCondition::ASCEND_DESCEND; + LOG_F(INFO, "进入上浮下潜模式"); +} + +// FloatDown实现 +void FloatDown::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} diff --git a/src/pPowerManger/fsm/HighSpeedMode.cpp b/src/pPowerManger/fsm/HighSpeedMode.cpp new file mode 100644 index 0000000..91eb2e9 --- /dev/null +++ b/src/pPowerManger/fsm/HighSpeedMode.cpp @@ -0,0 +1,14 @@ +#include "PowerManagerFsm.hpp" + +void HighSpeedMode::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::HIGH_SPEED_MODE; + LOG_F(INFO, "进入高速模式"); +} + +// HighSpeedMode实现 +void HighSpeedMode::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} \ No newline at end of file diff --git a/src/pPowerManger/fsm/InitState.cpp b/src/pPowerManger/fsm/InitState.cpp new file mode 100644 index 0000000..09f74d8 --- /dev/null +++ b/src/pPowerManger/fsm/InitState.cpp @@ -0,0 +1,9 @@ +#include "PowerManagerFsm.hpp" + +// InitState实现 +void InitState::entry() { + PowerManagerFsm::entry(); + LOG_F(INFO, "进入初始化状态"); + pm->initControlCmd(); + transit(); +} \ No newline at end of file diff --git a/src/pPowerManger/PowerManagerFsm.cpp b/src/pPowerManger/fsm/PowerManagerFsm.cpp similarity index 86% rename from src/pPowerManger/PowerManagerFsm.cpp rename to src/pPowerManger/fsm/PowerManagerFsm.cpp index fe040a8..00d9772 100644 --- a/src/pPowerManger/PowerManagerFsm.cpp +++ b/src/pPowerManger/fsm/PowerManagerFsm.cpp @@ -1,6 +1,6 @@ #include "PowerManagerFsm.hpp" -#include "PowerManger.h" -#include "loguru.hpp" +#include "../PowerManger.h" +#include "../loguru.hpp" #include #include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h" @@ -13,10 +13,8 @@ void PowerManagerFsm::react(TaskStopEvent const &e) { }; void PowerManagerFsm::react(CycleTriggeredEvent const &){ - if(pm->currentMod != RunMode::Debug) - { - - } + // 更新当前设备状态 + pm->m_currentDriverState = pm->m_currentDriverState; } bool PowerManagerFsm::handPowerProtection(DevCmdExt const &e){ if(pm->workCondition > WorkCondition::REMOTE_CONTROL){ @@ -42,6 +40,10 @@ bool PowerManagerFsm::handPowerProtection(DevCmdExt const &e){ } } } + +void PowerManagerFsm::react(DeviceCmd const &){ + LOG_F(INFO, "DeviceCmd received"); +} void PowerManagerFsm::react(TaskStartEvent const &e){ LOG_F(INFO, "TaskStartEvent received - type: %d, enableBowRudder: %d, enableBuoyancyAdjustment: %d", e.type, e.enableBowRudder, e.enableBuoyancyAdjustment); switch (e.type) @@ -1736,32 +1738,6 @@ void PowerManagerFsm::react(DevCmdExt const &e) { } } -void StandbyState::react(DevCmdExt const &e) -{ - LOG_F(INFO, "StandbyState::react(DevCmdExt const &e)"); - //正常模式下,不允许执行DevCmdExt - if (pm->currentMod == RunMode::Normal ) - { - LOG_F(INFO, "正常模式下,不允许执行DevCmdExt"); - } - else if (pm->currentMod == RunMode::Test) - { - if(handPowerProtection(e)) - PowerManagerFsm::react(e); - else - LOG_F(INFO, "DevCmdExt 执行失败"); - } - else if (pm->currentMod == RunMode::Debug) - { - LOG_F(INFO, "调试模式下,直接执行DevCmdExt"); - PowerManagerFsm::react(e); - } - else - { - LOG_F(INFO, "当前模式未知"); - } -} - void PowerManagerFsm::basicNavigationFault(FaultEvent const &e) { LOG_F(INFO, "basicNavigationFault"); @@ -2042,51 +2018,9 @@ void PowerManagerFsm::react(FaultEvent const &e) emergencySystemFault(e); sensorSystemFault(e); } -// InitState实现 -void InitState::entry() { - PowerManagerFsm::entry(); - LOG_F(INFO, "进入初始化状态"); - pm->initControlCmd(); - transit(); -} -void StandbyState::react(StandbyEvent const &) { - transit(); -} -void StandbyState::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void StandbyState::handlePowerOn() { - LOG_F(INFO,"动力电上电"); - PowerManagerFsm::pm->m_CcuColCmd.powerBatCmd = 0x10; - if(PowerManagerFsm::pm->m_pmCurrentState.ccustate.fcuState == 0x04) - PowerManagerFsm::pm->m_CcuColCmd.fcuCmd = 0x02; -} - -// FaultState实现 -void FaultState::entry() { - PowerManagerFsm::entry(); - // PowerManagerFsm::pm->printState("FaultState", "进入故障状态"); - if(pm->m_missionState.type == TaskType::THROW_LOAD) - { - LOG_F(INFO, "检测到抛载,所有水声探测设备"); - } - else - { - // LOG_F(INFO, "检测到抛载,所有水声设备关闭"); - } -} - -void FaultState::react(FaultEvent const & e) { - LOG_F(INFO, "FaultState 处理故障事件"); -} - - void PowerManagerFsm::handelPowerCmd(){ switch (pm->m_msCmd.powerCMD) { @@ -2209,259 +2143,4 @@ void PowerManagerFsm::handleDeviceCmd() { } - -// 设置初始状态 -// ShoreBasedReady实现 -void ShoreBasedReady::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -// StandbyState实现 -void StandbyState::entry() { - PowerManagerFsm::entry(); - pm->m_driver.getSTANDBYTable(&pm->m_subDisSysCmd); - pm->m_CcuColCmd.fcuCmd = FcuCommand::Stop; - pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop; - pm->workCondition = WorkCondition::STANDBY; - LOG_F(INFO, "WorkCondition %d", pm->workCondition); -} - -void ShoreBasedReady::entry() { - PowerManagerFsm::entry(); - pm->m_driver.getSHORE_BASED_READYable(&pm->m_subDisSysCmd); - pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; - pm->workCondition = WorkCondition::CHANING; - //依次接入执行机构动力电设备 - //TODO:接入执行机构动力电设备 - pm->workCondition = WorkCondition::SHORE_BASED_READY; - LOG_F(INFO, "进入岸基备航状态"); -} - -void WaterBasedReady::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::CHANING; - pm->m_driver.getWATER_BASED_READYable(&pm->m_subDisSysCmd); - pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; - //依次接入执行机构动力电设备 - //TODO:接入执行机构动力电设备 - pm->workCondition = WorkCondition::WATER_BASED_READY; - LOG_F(INFO, "进入水中备航状态"); -} - -void CruiseMode::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::CHANING; - pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); - //依次接入执行机构动力电设备 - //TODO:接入执行机构动力电设备 - - //TODO:解除非必要动力电设备 - pm->workCondition = WorkCondition::CRUISE_MODE; - LOG_F(INFO, "进入巡航模式"); -} - -void FloatAdjust::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::CHANING; - //与巡航模式相同 - pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); - //依次接入执行机构动力电设备 - //TODO:接入执行机构动力电设备 - - //TODO:解除非必要动力电设备 - pm->workCondition = WorkCondition::BUOYANCY_ADJUST; - LOG_F(INFO, "进入浮调模式"); -} - -void FloatDown::entry() { - PowerManagerFsm::entry(); - //与巡航模式相同 - pm->m_driver.getCRUISE_MODEable(&pm->m_subDisSysCmd); - //依次接入执行机构动力电设备 - //TODO:接入执行机构动力电设备 - - //TODO:解除非必要动力电设备 - pm->workCondition = WorkCondition::ASCEND_DESCEND; - LOG_F(INFO, "进入上浮下潜模式"); -} - - -// FloatDown实现 -void FloatDown::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -// WaterBasedReady实现 -void WaterBasedReady::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - - - -// CruiseMode实现 -void CruiseMode::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - - - -// HighSpeedMode实现 -void HighSpeedMode::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void HighSpeedMode::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::HIGH_SPEED_MODE; - LOG_F(INFO, "进入高速模式"); -} - -// FloatAdjust实现 -void FloatAdjust::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -// UnderwaterSurvey实现 -void UnderwaterSurvey::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void UnderwaterSurvey::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::UNDERWATER_RECON; - LOG_F(INFO, "进入水下侦查模式"); -} - -// SurfaceSurvey实现 -void SurfaceSurvey::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void SurfaceSurvey::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::SURFACE_RECON; - LOG_F(INFO, "进入水面侦查模式"); -} - -// DJMode实现 -void DJMode::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void DJMode::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::DJ_MODE; - LOG_F(INFO, "进入DJ模式"); -} - -// RemoteControl实现 -void RemoteControl::react(MasterCommandEvent const &) { - PowerManagerFsm::handelPowerCmd(); - PowerManagerFsm::handleModCmd(); - PowerManagerFsm::handleWorkCmd(); -} - -void RemoteControl::entry() { - PowerManagerFsm::entry(); - pm->workCondition = WorkCondition::REMOTE_CONTROL; - LOG_F(INFO, "进入遥控工况"); -} - - - -// void StandbyState::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// //日志保存错误 -// LOG_F(WARNING, "待机状态无法直接启动任务"); -// } -//岸基备航 -// void ShoreBasedReady::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// //日志保存错误 -// LOG_F(WARNING, "岸基备航状态无法直接启动任务"); -// } -// //水中备航 -// void WaterBasedReady::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "开始执行启动任务"); -// } - -// //遥控工况 -// void RemoteControl::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "开始执行启动任务"); -// } - -// //巡航模式 -// void CruiseMode::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入巡航模式"); -// } - -// //高速模式 -// void HighSpeedMode::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入高速模式"); -// } - -// //浮调模式 -// void FloatAdjust::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入浮调模式"); -// } - -// //水下侦查 -// void UnderwaterSurvey::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入水下侦查模式"); -// } - -// //水面侦查 -// void SurfaceSurvey::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入水面侦查模式"); -// } - -// //DJ模式 -// void DJMode::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入DJ模式"); -// } - -// // 上浮下潜 -// void FloatDown::react(TaskStart const &) -// { -// LOG_F(INFO, "接收到任务启动信息"); -// LOG_F(INFO, "进入上浮下潜模式"); -// } - - FSM_INITIAL_STATE(PowerManagerFsm, InitState); \ No newline at end of file diff --git a/src/pPowerManger/PowerManagerFsm.hpp b/src/pPowerManger/fsm/PowerManagerFsm.hpp similarity index 98% rename from src/pPowerManger/PowerManagerFsm.hpp rename to src/pPowerManger/fsm/PowerManagerFsm.hpp index bf230b6..21fb3d6 100644 --- a/src/pPowerManger/PowerManagerFsm.hpp +++ b/src/pPowerManger/fsm/PowerManagerFsm.hpp @@ -1,15 +1,15 @@ #ifndef POWER_MANAGER_FSM_HPP #define POWER_MANAGER_FSM_HPP #include "tinyfsm.hpp" -#include "loguru.hpp" +#include "../loguru.hpp" #include #include // 新增头文件 #include // 新增头文件 #include // 新增头文件,用于localtime函数 #include // 新增头文件,用于demangle功能 -#include "pmSysvariable.h" -#include "driver.h" -#include "PowerManger.h" +#include "../pmSysvariable.h" +#include "../driver.h" +#include "../PowerManger.h" // 前向声明 class PowerManger; @@ -73,7 +73,7 @@ public: virtual void react(InitEvent const &) {}; virtual void react(StandbyEvent const &) { }; virtual void react(MasterCommandEvent const &) { LOG_F(INFO, "MasterCommandEvent");}; - virtual void react(DeviceCmd const &) { LOG_F(INFO, "DeviceCmd"); }; + virtual void react(DeviceCmd const &); virtual void react(DevCmdExt const &e); virtual void react(TaskStartEvent const &e); virtual void react(FaultEvent const &e); @@ -180,17 +180,6 @@ class CruiseMode : public PowerManagerFsm { private: // void handlePowerCommands(); }; - -// 高速模式 -class HighSpeedMode : public PowerManagerFsm { - public: - void entry() override; - void react(MasterCommandEvent const &) override; - // void react(DeviceCmd const &) override; - // void react(TaskStart const &) override; - private: - // void handlePowerCommands(); -}; // 上浮下潜 class FloatDown : public PowerManagerFsm { public: @@ -201,6 +190,17 @@ class FloatDown : public PowerManagerFsm { private: // void handlePowerCommands(); }; +// 高速模式 +class HighSpeedMode : public PowerManagerFsm { + public: + void entry() override; + void react(MasterCommandEvent const &) override; + // void react(DeviceCmd const &) override; + // void react(TaskStart const &) override; + private: + // void handlePowerCommands(); +}; + // 浮调模式 class FloatAdjust : public PowerManagerFsm { public: diff --git a/src/pPowerManger/fsm/RemoteControl.cpp b/src/pPowerManger/fsm/RemoteControl.cpp new file mode 100644 index 0000000..6b77fe9 --- /dev/null +++ b/src/pPowerManger/fsm/RemoteControl.cpp @@ -0,0 +1,16 @@ +#include "PowerManagerFsm.hpp" + +// RemoteControl实现 +void RemoteControl::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + +void RemoteControl::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::REMOTE_CONTROL; + LOG_F(INFO, "进入遥控工况"); +} + + diff --git a/src/pPowerManger/fsm/ShoreBasedReady.cpp b/src/pPowerManger/fsm/ShoreBasedReady.cpp new file mode 100644 index 0000000..429b5bf --- /dev/null +++ b/src/pPowerManger/fsm/ShoreBasedReady.cpp @@ -0,0 +1,21 @@ +#include "PowerManagerFsm.hpp" + +// ShoreBasedReady实现 +void ShoreBasedReady::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + + + +void ShoreBasedReady::entry() { + PowerManagerFsm::entry(); + pm->m_driver.getSHORE_BASED_READYable(&pm->m_subDisSysCmd); + pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; + pm->workCondition = WorkCondition::CHANING; + //依次接入执行机构动力电设备 + //TODO:接入执行机构动力电设备 + pm->workCondition = WorkCondition::SHORE_BASED_READY; + LOG_F(INFO, "进入岸基备航状态"); +} \ No newline at end of file diff --git a/src/pPowerManger/fsm/StandbyState.cpp b/src/pPowerManger/fsm/StandbyState.cpp new file mode 100644 index 0000000..4d4b98e --- /dev/null +++ b/src/pPowerManger/fsm/StandbyState.cpp @@ -0,0 +1,55 @@ +#include "PowerManagerFsm.hpp" + +// StandbyState实现 +void StandbyState::entry() { + PowerManagerFsm::entry(); + pm->m_driver.getSTANDBYTable(&pm->m_subDisSysCmd); + pm->m_CcuColCmd.fcuCmd = FcuCommand::Stop; + // pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Stop; + pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; + pm->workCondition = WorkCondition::STANDBY; + LOG_F(INFO, "WorkCondition %d", pm->workCondition); +} +void StandbyState::react(StandbyEvent const &) { + transit(); +} +void StandbyState::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + +void StandbyState::react(DevCmdExt const &e) +{ + LOG_F(INFO, "StandbyState::react(DevCmdExt const &e)"); + //正常模式下,不允许执行DevCmdExt + if (pm->currentMod == RunMode::Normal ) + { + LOG_F(INFO, "正常模式下,不允许执行DevCmdExt"); + } + else if (pm->currentMod == RunMode::Test) + { + if(handPowerProtection(e)) + PowerManagerFsm::react(e); + else + LOG_F(INFO, "DevCmdExt 执行失败"); + } + else if (pm->currentMod == RunMode::Debug) + { + LOG_F(INFO, "调试模式下,直接执行DevCmdExt"); + PowerManagerFsm::react(e); + } + else + { + LOG_F(INFO, "当前模式未知"); + } +} + + +void StandbyState::handlePowerOn() { + LOG_F(INFO,"动力电上电"); + //TODO: 电源上电 更新协议 + // PowerManagerFsm::pm->m_CcuColCmd.powerBatCmd = 0x10; + // if(PowerManagerFsm::pm->m_pmCurrentState.ccustate.fcuState == 0x04) + // PowerManagerFsm::pm->m_CcuColCmd.fcuCmd = 0x02; +} \ No newline at end of file diff --git a/src/pPowerManger/fsm/SurfaceSurvey.cpp b/src/pPowerManger/fsm/SurfaceSurvey.cpp new file mode 100644 index 0000000..f6b9236 --- /dev/null +++ b/src/pPowerManger/fsm/SurfaceSurvey.cpp @@ -0,0 +1,14 @@ +#include "PowerManagerFsm.hpp" + +// SurfaceSurvey实现 +void SurfaceSurvey::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} + +void SurfaceSurvey::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::SURFACE_RECON; + LOG_F(INFO, "进入水面侦查模式"); +} \ No newline at end of file diff --git a/src/pPowerManger/fsm/UnderwaterSurvey.cpp b/src/pPowerManger/fsm/UnderwaterSurvey.cpp new file mode 100644 index 0000000..e4958b7 --- /dev/null +++ b/src/pPowerManger/fsm/UnderwaterSurvey.cpp @@ -0,0 +1,15 @@ +#include "PowerManagerFsm.hpp" + +void UnderwaterSurvey::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::UNDERWATER_RECON; + LOG_F(INFO, "进入水下侦查模式"); +} + + +// UnderwaterSurvey实现 +void UnderwaterSurvey::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} diff --git a/src/pPowerManger/fsm/WaterBasedReady.cpp b/src/pPowerManger/fsm/WaterBasedReady.cpp new file mode 100644 index 0000000..ff61816 --- /dev/null +++ b/src/pPowerManger/fsm/WaterBasedReady.cpp @@ -0,0 +1,20 @@ +#include "PowerManagerFsm.hpp" + + +void WaterBasedReady::entry() { + PowerManagerFsm::entry(); + pm->workCondition = WorkCondition::CHANING; + pm->m_driver.getWATER_BASED_READYable(&pm->m_subDisSysCmd); + pm->m_CcuColCmd.powerBatCmd = BatteryCommand::Start; + //依次接入执行机构动力电设备 + //TODO:接入执行机构动力电设备 + pm->workCondition = WorkCondition::WATER_BASED_READY; + LOG_F(INFO, "进入水中备航状态"); +} + +// WaterBasedReady实现 +void WaterBasedReady::react(MasterCommandEvent const &) { + PowerManagerFsm::handelPowerCmd(); + PowerManagerFsm::handleModCmd(); + PowerManagerFsm::handleWorkCmd(); +} diff --git a/src/pPowerManger/tinyfsm.hpp b/src/pPowerManger/fsm/tinyfsm.hpp similarity index 100% rename from src/pPowerManger/tinyfsm.hpp rename to src/pPowerManger/fsm/tinyfsm.hpp diff --git a/src/pPowerManger/msg/uDevice_secdistState.h b/src/pPowerManger/msg/uDevice_secdistState.h new file mode 100644 index 0000000..f61c440 --- /dev/null +++ b/src/pPowerManger/msg/uDevice_secdistState.h @@ -0,0 +1,451 @@ +#ifndef UDEVICE_SECDISTSTATE_H +#define UDEVICE_SECDISTSTATE_H +#include +#include +#include "../driver.h" +#include "../loguru.hpp" + +class uDevice_secdistStateMsg +{ +private: + /* data */ +public: + uDevice_secdistStateMsg(){}; + ~uDevice_secdistStateMsg(){}; + std::string key_fb = "uDevice_secdistState_st"; + std::string key_cmd = "uPower_secdistState_cmd"; + + struct DeviceSecdistState + { + // UNIT1 + u_int8_t bowCover1; + u_int8_t bowCover2; + u_int8_t bowCover3; + u_int8_t bowCover4; + u_int8_t bowCover5; + u_int8_t bowCover6; + u_int8_t singleBeamSonar1; + u_int8_t singleBeamSonar2; + u_int8_t singleBeamSonar3; + u_int8_t singleBeamSonar4; + u_int8_t singleBeamSonar5; + u_int8_t singleBeamSonar6; + u_int8_t forwardSonar; + u_int8_t depth3; + u_int8_t soundVeloc; + u_int8_t bowRudderServo; + u_int8_t bowRudderDeploy; + u_int8_t ctd1; + u_int8_t waterInject; + + // UNIT2 + u_int8_t sideSonar; + u_int8_t bowWaterInet1; + u_int8_t bowWaterInet2; + u_int8_t bowWaterInet3; + u_int8_t bowWaterInet4; + u_int8_t bowWaterInet5; + u_int8_t bowWaterInet6; + u_int8_t bowWaterInet7; + u_int8_t bowWaterInet8; + u_int8_t launchControler; + u_int8_t electSensor; + u_int8_t lowFreqSonar; + + // UNIT3 + u_int8_t buoyancyAdjust1; + u_int8_t buoyancyAdjust2; + u_int8_t buoyancyAdjust3; + u_int8_t USBL; + u_int8_t depth1; + u_int8_t commDev; + u_int8_t mastLiftingServo; + u_int8_t DVL; + u_int8_t ADCP; + u_int8_t inOutLetWater1; + u_int8_t inOutLetWater2; + + // UNIT4 + u_int8_t singleBeamSonar7; + u_int8_t singleBeamSonar8; + u_int8_t buoyage; + u_int8_t bowThrow; + u_int8_t depth2; + u_int8_t thruster; + u_int8_t dragSonar; + u_int8_t haulingMachine; + u_int8_t buoyancyAdjust4; + u_int8_t buoyancyAdjust5; + u_int8_t sternRudderServo1; + u_int8_t sternRudderServo2; + u_int8_t sternRudderServo3; + u_int8_t sternRudderServo4; + u_int8_t ctd2; + u_int8_t commDevStern; + u_int8_t inOutLetWater3; + + // UNIT5 + u_int8_t secINS; + u_int8_t photoSensor; + u_int8_t sternThrow; + u_int8_t mainINS; + } deviceSecdistState; + + + + bool parseSecdistStateFromJson(DeviceSecdistState &state, const std::string &strJson){ + Json::Value root; + Json::CharReaderBuilder readerBuilder; + std::unique_ptr reader(readerBuilder.newCharReader()); + std::string errors; + + if(!reader->parse(strJson.c_str(), strJson.c_str() + strJson.length(), &root, &errors)){ + LOG_F(ERROR, "Failed to parse JSON: %s", errors.c_str()); + return false; + } + + auto checkField = [&root](const std::string& field) -> bool { + if(!root.isMember(field) || !root[field].isUInt()) { + // std::cerr << "Missing or invalid field: " << field << std::endl; + LOG_F(ERROR, "Missing or invalid field: %s", field.c_str()); + return false; + } + return true; + }; + + bool ok = true; + + // UNIT1 + if(!checkField("bowCover1_uint8")) ok=false; state.bowCover1 = root["bowCover1_uint8"].asUInt(); + if(!checkField("bowCover2_uint8")) ok=false; state.bowCover2 = root["bowCover2_uint8"].asUInt(); + if(!checkField("bowCover3_uint8")) ok=false; state.bowCover3 = root["bowCover3_uint8"].asUInt(); + if(!checkField("bowCover4_uint8")) ok=false; state.bowCover4 = root["bowCover4_uint8"].asUInt(); + if(!checkField("bowCover5_uint8")) ok=false; state.bowCover5 = root["bowCover5_uint8"].asUInt(); + if(!checkField("bowCover6_uint8")) ok=false; state.bowCover6 = root["bowCover6_uint8"].asUInt(); + if(!checkField("singleBeamSonar1_uint8")) ok=false; state.singleBeamSonar1 = root["singleBeamSonar1_uint8"].asUInt(); + if(!checkField("singleBeamSonar2_uint8")) ok=false; state.singleBeamSonar2 = root["singleBeamSonar2_uint8"].asUInt(); + if(!checkField("singleBeamSonar3_uint8")) ok=false; state.singleBeamSonar3 = root["singleBeamSonar3_uint8"].asUInt(); + if(!checkField("singleBeamSonar4_uint8")) ok=false; state.singleBeamSonar4 = root["singleBeamSonar4_uint8"].asUInt(); + if(!checkField("singleBeamSonar5_uint8")) ok=false; state.singleBeamSonar5 = root["singleBeamSonar5_uint8"].asUInt(); + if(!checkField("singleBeamSonar6_uint8")) ok=false; state.singleBeamSonar6 = root["singleBeamSonar6_uint8"].asUInt(); + if(!checkField("forwardSonar_uint8")) ok=false; state.forwardSonar = root["forwardSonar_uint8"].asUInt(); + if(!checkField("depth3_uint8")) ok=false; state.depth3 = root["depth3_uint8"].asUInt(); + if(!checkField("soundVeloc_uint8")) ok=false; state.soundVeloc = root["soundVeloc_uint8"].asUInt(); + if(!checkField("bowRudderServo_uint8")) ok=false; state.bowRudderServo = root["bowRudderServo_uint8"].asUInt(); + if(!checkField("bowRudderDeploy_uint8")) ok=false; state.bowRudderDeploy = root["bowRudderDeploy_uint8"].asUInt(); + if(!checkField("ctd1_uint8")) ok=false; state.ctd1 = root["ctd1_uint8"].asUInt(); + if(!checkField("waterInject_uint8")) ok=false; state.waterInject = root["waterInject_uint8"].asUInt(); + + // UNIT2 + if(!checkField("sideSonar_uint8")) ok=false; state.sideSonar = root["sideSonar_uint8"].asUInt(); + if(!checkField("bowWaterInet1_uint8")) ok=false; state.bowWaterInet1 = root["bowWaterInet1_uint8"].asUInt(); + if(!checkField("bowWaterInet2_uint8")) ok=false; state.bowWaterInet2 = root["bowWaterInet2_uint8"].asUInt(); + if(!checkField("bowWaterInet3_uint8")) ok=false; state.bowWaterInet3 = root["bowWaterInet3_uint8"].asUInt(); + if(!checkField("bowWaterInet4_uint8")) ok=false; state.bowWaterInet4 = root["bowWaterInet4_uint8"].asUInt(); + if(!checkField("bowWaterInet5_uint8")) ok=false; state.bowWaterInet5 = root["bowWaterInet5_uint8"].asUInt(); + if(!checkField("bowWaterInet6_uint8")) ok=false; state.bowWaterInet6 = root["bowWaterInet6_uint8"].asUInt(); + if(!checkField("bowWaterInet7_uint8")) ok=false; state.bowWaterInet7 = root["bowWaterInet7_uint8"].asUInt(); + if(!checkField("bowWaterInet8_uint8")) ok=false; state.bowWaterInet8 = root["bowWaterInet8_uint8"].asUInt(); + if(!checkField("launchControler_uint8")) ok=false; state.launchControler = root["launchControler_uint8"].asUInt(); + if(!checkField("electSensor_uint8")) ok=false; state.electSensor = root["electSensor_uint8"].asUInt(); + if(!checkField("lowFreqSonar_uint8")) ok=false; state.lowFreqSonar = root["lowFreqSonar_uint8"].asUInt(); + + // UNIT3 + if(!checkField("buoyancyAdjust1_uint8")) ok=false; state.buoyancyAdjust1 = root["buoyancyAdjust1_uint8"].asUInt(); + if(!checkField("buoyancyAdjust2_uint8")) ok=false; state.buoyancyAdjust2 = root["buoyancyAdjust2_uint8"].asUInt(); + if(!checkField("buoyancyAdjust3_uint8")) ok=false; state.buoyancyAdjust3 = root["buoyancyAdjust3_uint8"].asUInt(); + if(!checkField("USBL_uint8")) ok=false; state.USBL = root["USBL_uint8"].asUInt(); + if(!checkField("depth1_uint8")) ok=false; state.depth1 = root["depth1_uint8"].asUInt(); + if(!checkField("commDev_uint8")) ok=false; state.commDev = root["commDev_uint8"].asUInt(); + if(!checkField("mastLiftingServo_uint8")) ok=false; state.mastLiftingServo = root["mastLiftingServo_uint8"].asUInt(); + if(!checkField("DVL_uint8")) ok=false; state.DVL = root["DVL_uint8"].asUInt(); + if(!checkField("ADCP_uint8")) ok=false; state.ADCP = root["ADCP_uint8"].asUInt(); + if(!checkField("inOutLetWater1_uint8")) ok=false; state.inOutLetWater1 = root["inOutLetWater1_uint8"].asUInt(); + if(!checkField("inOutLetWater2_uint8")) ok=false; state.inOutLetWater2 = root["inOutLetWater2_uint8"].asUInt(); + + // UNIT4 + if(!checkField("singleBeamSonar7_uint8")) ok=false; state.singleBeamSonar7 = root["singleBeamSonar7_uint8"].asUInt(); + if(!checkField("singleBeamSonar8_uint8")) ok=false; state.singleBeamSonar8 = root["singleBeamSonar8_uint8"].asUInt(); + if(!checkField("buoyage_uint8")) ok=false; state.buoyage = root["buoyage_uint8"].asUInt(); + if(!checkField("bowThrow_uint8")) ok=false; state.bowThrow = root["bowThrow_uint8"].asUInt(); + if(!checkField("depth2_uint8")) ok=false; state.depth2 = root["depth2_uint8"].asUInt(); + if(!checkField("thruster_uint8")) ok=false; state.thruster = root["thruster_uint8"].asUInt(); + if(!checkField("dragSonar_uint8")) ok=false; state.dragSonar = root["dragSonar_uint8"].asUInt(); + if(!checkField("haulingMachine_uint8")) ok=false; state.haulingMachine = root["haulingMachine_uint8"].asUInt(); + if(!checkField("buoyancyAdjust4_uint8")) ok=false; state.buoyancyAdjust4 = root["buoyancyAdjust4_uint8"].asUInt(); + if(!checkField("buoyancyAdjust5_uint8")) ok=false; state.buoyancyAdjust5 = root["buoyancyAdjust5_uint8"].asUInt(); + if(!checkField("sternRudderServo1_uint8")) ok=false; state.sternRudderServo1 = root["sternRudderServo1_uint8"].asUInt(); + if(!checkField("sternRudderServo2_uint8")) ok=false; state.sternRudderServo2 = root["sternRudderServo2_uint8"].asUInt(); + if(!checkField("sternRudderServo3_uint8")) ok=false; state.sternRudderServo3 = root["sternRudderServo3_uint8"].asUInt(); + if(!checkField("sternRudderServo4_uint8")) ok=false; state.sternRudderServo4 = root["sternRudderServo4_uint8"].asUInt(); + if(!checkField("ctd2_uint8")) ok=false; state.ctd2 = root["ctd2_uint8"].asUInt(); + if(!checkField("commDevStern_uint8")) ok=false; state.commDevStern = root["commDevStern_uint8"].asUInt(); + if(!checkField("inOutLetWater3_uint8")) ok=false; state.inOutLetWater3 = root["inOutLetWater3_uint8"].asUInt(); + + // UNIT5 + if(!checkField("secINS_uint8")) ok=false; state.secINS = root["secINS_uint8"].asUInt(); + if(!checkField("photoSensor_uint8")) ok=false; state.photoSensor = root["photoSensor_uint8"].asUInt(); + if(!checkField("sternThrow_uint8")) ok=false; state.sternThrow = root["sternThrow_uint8"].asUInt(); + if(!checkField("mainINS_uint8")) ok=false; state.mainINS = root["mainINS_uint8"].asUInt(); + + return ok; + }; + std::string buildSecdistStateToJson(DeviceSecdistState &state){ + Json::Value root; + + // UNIT1 + root["bowCover1_uint8"] = state.bowCover1; + root["bowCover2_uint8"] = state.bowCover2; + root["bowCover3_uint8"] = state.bowCover3; + root["bowCover4_uint8"] = state.bowCover4; + root["bowCover5_uint8"] = state.bowCover5; + root["bowCover6_uint8"] = state.bowCover6; + root["singleBeamSonar1_uint8"] = state.singleBeamSonar1; + root["singleBeamSonar2_uint8"] = state.singleBeamSonar2; + root["singleBeamSonar3_uint8"] = state.singleBeamSonar3; + root["singleBeamSonar4_uint8"] = state.singleBeamSonar4; + root["singleBeamSonar5_uint8"] = state.singleBeamSonar5; + root["singleBeamSonar6_uint8"] = state.singleBeamSonar6; + root["forwardSonar_uint8"] = state.forwardSonar; + root["depth3_uint8"] = state.depth3; + root["soundVeloc_uint8"] = state.soundVeloc; + root["bowRudderServo_uint8"] = state.bowRudderServo; + root["bowRudderDeploy_uint8"] = state.bowRudderDeploy; + root["ctd1_uint8"] = state.ctd1; + root["waterInject_uint8"] = state.waterInject; + + // UNIT2 + root["sideSonar_uint8"] = state.sideSonar; + root["bowWaterInet1_uint8"] = state.bowWaterInet1; + root["bowWaterInet2_uint8"] = state.bowWaterInet2; + root["bowWaterInet3_uint8"] = state.bowWaterInet3; + root["bowWaterInet4_uint8"] = state.bowWaterInet4; + root["bowWaterInet5_uint8"] = state.bowWaterInet5; + root["bowWaterInet6_uint8"] = state.bowWaterInet6; + root["bowWaterInet7_uint8"] = state.bowWaterInet7; + root["bowWaterInet8_uint8"] = state.bowWaterInet8; + root["launchControler_uint8"] = state.launchControler; + root["electSensor_uint8"] = state.electSensor; + root["lowFreqSonar_uint8"] = state.lowFreqSonar; + + // UNIT3 + root["buoyancyAdjust1_uint8"] = state.buoyancyAdjust1; + root["buoyancyAdjust2_uint8"] = state.buoyancyAdjust2; + root["buoyancyAdjust3_uint8"] = state.buoyancyAdjust3; + root["USBL_uint8"] = state.USBL; + root["depth1_uint8"] = state.depth1; + root["commDev_uint8"] = state.commDev; + root["mastLiftingServo_uint8"] = state.mastLiftingServo; + root["DVL_uint8"] = state.DVL; + root["ADCP_uint8"] = state.ADCP; + root["inOutLetWater1_uint8"] = state.inOutLetWater1; + root["inOutLetWater2_uint8"] = state.inOutLetWater2; + + // UNIT4 + root["singleBeamSonar7_uint8"] = state.singleBeamSonar7; + root["singleBeamSonar8_uint8"] = state.singleBeamSonar8; + root["buoyage_uint8"] = state.buoyage; + root["bowThrow_uint8"] = state.bowThrow; + root["depth2_uint8"] = state.depth2; + root["thruster_uint8"] = state.thruster; + root["dragSonar_uint8"] = state.dragSonar; + root["haulingMachine_uint8"] = state.haulingMachine; + root["buoyancyAdjust4_uint8"] = state.buoyancyAdjust4; + root["buoyancyAdjust5_uint8"] = state.buoyancyAdjust5; + root["sternRudderServo1_uint8"] = state.sternRudderServo1; + root["sternRudderServo2_uint8"] = state.sternRudderServo2; + root["sternRudderServo3_uint8"] = state.sternRudderServo3; + root["sternRudderServo4_uint8"] = state.sternRudderServo4; + root["ctd2_uint8"] = state.ctd2; + root["commDevStern_uint8"] = state.commDevStern; + root["inOutLetWater3_uint8"] = state.inOutLetWater3; + + // UNIT5 + root["secINS_uint8"] = state.secINS; + root["photoSensor_uint8"] = state.photoSensor; + root["sternThrow_uint8"] = state.sternThrow; + root["mainINS_uint8"] = state.mainINS; + + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; // 紧凑格式,无缩进 + return Json::writeString(writerBuilder, root); + }; + + bool converFromDriverTable(DeviceSecdistState &state,const DriverTable &driver){ + // UNIT1 + state.bowCover1 = driver.bowCover1; + state.bowCover2 = driver.bowCover2; + state.bowCover3 = driver.bowCover3; + state.bowCover4 = driver.bowCover4; + state.bowCover5 = driver.bowCover5; + state.bowCover6 = driver.bowCover6; + state.singleBeamSonar1 = driver.singleBeamSonar1; + state.singleBeamSonar2 = driver.singleBeamSonar2; + state.singleBeamSonar3 = driver.singleBeamSonar3; + state.singleBeamSonar4 = driver.singleBeamSonar4; + state.singleBeamSonar5 = driver.singleBeamSonar5; + state.singleBeamSonar6 = driver.singleBeamSonar6; + state.forwardSonar = driver.forwardSonar; + state.depth3 = driver.depth3; + state.soundVeloc = driver.soundVeloc; + state.bowRudderServo = driver.bowRudderServo1 | driver.bowRudderServo2; + state.bowRudderDeploy = driver.bowRudderDeploy; + state.ctd1 = driver.ctd1; + state.waterInject = driver.waterInject; + + // UNIT2 + state.sideSonar = driver.sideSonar; + state.bowWaterInet1 = driver.bowWaterlnet1; + state.bowWaterInet2 = driver.bowWaterlnet2; + state.bowWaterInet3 = driver.bowWaterlnet3; + state.bowWaterInet4 = driver.bowWaterlnet4; + state.bowWaterInet5 = driver.bowWaterlnet5; + state.bowWaterInet6 = driver.bowWaterlnet6; + state.bowWaterInet7 = driver.bowWaterlnet7; + state.bowWaterInet8 = driver.bowWaterlnet8; + state.launchControler = driver.launchControler; + state.electSensor = driver.electSensor; + state.lowFreqSonar = driver.lowFreqSonar; + + // UNIT3 + state.buoyancyAdjust1 = driver.buoyancyAdjust1; + state.buoyancyAdjust2 = driver.buoyancyAdjust2; + state.buoyancyAdjust3 = driver.buoyancyAdjust3; + state.USBL = driver.USBL; + state.depth1 = driver.depth1; + state.commDev = driver.commMast; + state.mastLiftingServo = driver.mastLiftingServo; + state.DVL = driver.DVL; + state.ADCP = driver.DVL; // Assuming ADCP is same as DVL + state.inOutLetWater1 = driver.inputWaterSensor1; + state.inOutLetWater2 = driver.inputWaterSensor2; + + // UNIT4 + state.singleBeamSonar7 = driver.singleBeamSonar7; + state.singleBeamSonar8 = driver.singleBeamSonar8; + state.buoyage = driver.buoyage; + state.bowThrow = driver.bowThrow; + state.depth2 = driver.depth2; + state.thruster = driver.thruster; + state.haulingMachine = 0; // No corresponding field in DriverTable + state.buoyancyAdjust4 = driver.buoyancyAdjust4; + state.buoyancyAdjust5 = driver.buoyancyAdjust5; + state.sternRudderServo1 = driver.sternRudderServo1; + state.sternRudderServo2 = driver.sternRudderServo2; + state.sternRudderServo3 = driver.sternRudderServo3; + state.sternRudderServo4 = driver.sternRudderServo4; + state.ctd2 = driver.ctd2; + state.commDevStern = 0; // No corresponding field in DriverTable + state.inOutLetWater3 = driver.inputWaterSensor3; + + // UNIT5 + state.secINS = driver.ins; + state.photoSensor = driver.photoSensor; + state.sternThrow = driver.sternThrow; + state.mainINS = driver.ins; + + // 未映射字段 + // driver.overDeep1 + // driver.overDeep2 + // driver.ntp + state.dragSonar = 0; // Assuming dragSonar is same as lowFreqSonar + + + return true; + }; + + bool converToDriverTable(const DeviceSecdistState &state, DriverTable &driver){ + // UNIT1 + driver.bowCover1 = state.bowCover1; + driver.bowCover2 = state.bowCover2; + driver.bowCover3 = state.bowCover3; + driver.bowCover4 = state.bowCover4; + driver.bowCover5 = state.bowCover5; + driver.bowCover6 = state.bowCover6; + driver.singleBeamSonar1 = state.singleBeamSonar1; + driver.singleBeamSonar2 = state.singleBeamSonar2; + driver.singleBeamSonar3 = state.singleBeamSonar3; + driver.singleBeamSonar4 = state.singleBeamSonar4; + driver.singleBeamSonar5 = state.singleBeamSonar5; + driver.singleBeamSonar6 = state.singleBeamSonar6; + driver.forwardSonar = state.forwardSonar; + driver.depth3 = state.depth3; + driver.soundVeloc = state.soundVeloc; + driver.bowRudderServo1 = state.bowRudderServo; + driver.bowRudderServo2 = state.bowRudderServo; + driver.bowRudderDeploy = state.bowRudderDeploy; + driver.ctd1 = state.ctd1; + driver.waterInject = state.waterInject; + + // UNIT2 + driver.sideSonar = state.sideSonar; + driver.bowWaterlnet1 = state.bowWaterInet1; + driver.bowWaterlnet2 = state.bowWaterInet2; + driver.bowWaterlnet3 = state.bowWaterInet3; + driver.bowWaterlnet4 = state.bowWaterInet4; + driver.bowWaterlnet5 = state.bowWaterInet5; + driver.bowWaterlnet6 = state.bowWaterInet6; + driver.bowWaterlnet7 = state.bowWaterInet7; + driver.bowWaterlnet8 = state.bowWaterInet8; + driver.launchControler = state.launchControler; + driver.electSensor = state.electSensor; + driver.lowFreqSonar = state.lowFreqSonar; + + // UNIT3 + driver.buoyancyAdjust1 = state.buoyancyAdjust1; + driver.buoyancyAdjust2 = state.buoyancyAdjust2; + driver.buoyancyAdjust3 = state.buoyancyAdjust3; + driver.USBL = state.USBL; + driver.depth1 = state.depth1; + driver.commMast = state.commDev; + driver.ntp = 1; + driver.mastLiftingServo = state.mastLiftingServo; + driver.DVL = state.DVL; + driver.inputWaterSensor1 = state.inOutLetWater1; + driver.inputWaterSensor2 = state.inOutLetWater2; + driver.overDeep1 = (state.depth1 == 1) ? 1 : 0; + driver.overDeep2 = (state.depth2 == 1 || state.depth3 == 1) ? 1 : 0; + + // UNIT4 + driver.singleBeamSonar7 = state.singleBeamSonar7; + driver.singleBeamSonar8 = state.singleBeamSonar8; + driver.buoyage = state.buoyage; + driver.bowThrow = state.bowThrow; + driver.depth2 = state.depth2; + driver.thruster = state.thruster; + driver.buoyancyAdjust4 = state.buoyancyAdjust4; + driver.buoyancyAdjust5 = state.buoyancyAdjust5; + driver.sternRudderServo1 = state.sternRudderServo1; + driver.sternRudderServo2 = state.sternRudderServo2; + driver.sternRudderServo3 = state.sternRudderServo3; + driver.sternRudderServo4 = state.sternRudderServo4; + driver.ctd2 = state.ctd2; + driver.inputWaterSensor3 = state.inOutLetWater3; + + // UNIT5 + driver.ins = state.secINS | state.mainINS; + driver.photoSensor = state.photoSensor; + driver.sternThrow = state.sternThrow; + + return true; + } + + std::string buildMsg(DriverTable &driver){ + DeviceSecdistState s; + converFromDriverTable(s,driver); + return buildSecdistStateToJson(s); + }; + + bool parseMsg(const std::string &strJson,DriverTable &driver){ + DeviceSecdistState s; + if(!parseSecdistStateFromJson(s,strJson)){ + LOG_F(WARNING, "parseSecdistStateFromJson failed"); + return false; + } + converToDriverTable(s,driver); + return true; + }; +}; + + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_currentState_st.h b/src/pPowerManger/msg/uPower_currentState_st.h new file mode 100644 index 0000000..4a8e821 --- /dev/null +++ b/src/pPowerManger/msg/uPower_currentState_st.h @@ -0,0 +1,81 @@ +#ifndef U_POWER_CURRENTSTATE_ST_H +#define U_POWER_CURRENTSTATE_ST_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include + +class uPower_currentStateMsg +{ +private: + /* data */ +public: + uPower_currentStateMsg() { + memset(&state, 0, sizeof(state)); + }; + ~uPower_currentStateMsg() {}; + std::string key = "uPower_currentState_st"; + + pmState state; + std::string buildMsg(pmState state) + { + // 状态赋值 + Json::Value currentBusState; + currentBusState["HVBpowerBusVol_uint16"] = state.bus1State.powerBusVoltage; + currentBusState["HVBdcDc5Cur_uint16"] = state.bus1State.dcDc5ModuleCurrent; + currentBusState["HVBpowerBusCur_uint16"] = state.bus1State.powerBusCurrent; + currentBusState["HVBbusAVol_uint16"] = state.bus1State.busbarAVoltage; + currentBusState["HVBmotorCur_uint16"] = state.bus1State.propulsionMotorControlBoxCurrent; + currentBusState["HVBbusACur_uint16"] = state.bus1State.busbarACurrent; + currentBusState["HVBbatGroupCur_uint16"] = state.bus1State.lithiumBatteryGroupMeterCurrent; + currentBusState["HVBbowHVolDisBoxCur_uint16"] = state.bus1State.bowHighVoltageDistributionBoxCurrent; + currentBusState["HVBFTDev45Cur_uint16"] = state.bus1State.sternFTDevice45Current; + currentBusState["HVBtyzCur_uint16"] = state.bus1State.tyzReservedSwitchCurrent; + currentBusState["HVBsternRud1Cur_uint16"] = state.bus1State.sternRudderSwitch1Current; + currentBusState["HVBreservedCur1_uint16"] = state.bus1State.reservedCurrent1; + currentBusState["HVBsternRud2Cur_uint16"] = state.bus1State.sternRudderSwitch2Current; + currentBusState["HVBreservedCur2_uint16"] = state.bus1State.reservedCurrent2; + currentBusState["HVBfbCur_uint16"] = state.bus1State.fbReservedSwitchCurrent; + currentBusState["HVBreservedCur3_uint16"] = state.bus1State.reservedCurrent3; + + currentBusState["HVABbusBVol_uint16"] = state.bus2State.busbarBVoltage; + currentBusState["HVABbusBCur_uint16"] = state.bus2State.busbarBCurrent; + currentBusState["HVABFTDev123Cur_uint16"] = state.bus2State.bowFTDevice123Current; + currentBusState["HVABactCur_uint16"] = state.bus2State.actuatorCurrent; + currentBusState["HVABmastSteGeaCur_uint16"] = state.bus2State.mastSteeringGearControlBoxCurrent; + currentBusState["HVABxczCur_uint16"] = state.bus2State.xczCurrent; + currentBusState["HVABbowRudCur_uint16"] = state.bus2State.bowRudderControlBoxCurrent; + currentBusState["HVABopenWaterCur_uint16"] = state.bus2State.openWaterCoverStartCylinderCurrent; + + currentBusState["HVBBinsBusVol_uint16"] = state.bus3State.instrumentBusbarVoltage; + currentBusState["HVBBbowLowVolDisBoxCur_uint16"] = state.bus3State.bowLowVoltageDistributionBoxCurrent; + currentBusState["HVBBdcC1InsCur_uint16"] = state.bus3State.dcC1InstrumentDC48VCurrent; + currentBusState["HVBBreservedCur1_uint16"] = state.bus3State.reservedCurrent1; + currentBusState["HVBBemerBatCur_uint16"] = state.bus3State.emergencyLithiumBatteryGroup2Current; + currentBusState["HVBBbatInsCur_uint16"] = state.bus3State.lithiumBatteryGroupInstrumentCurrent; + currentBusState["HVBBunit4Cur_uint16"] = state.bus3State.unit4InstrumentDC48VCurrent; + currentBusState["HVBBreservedCur2_uint16"] = state.bus3State.reservedCurrent2; + currentBusState["HVBBemer2BusVol_uint16"] = state.bus3State.emergency2BusbarVoltage; + currentBusState["HVBBCCUCur_uint16"] = state.bus3State.compositeEnergyManagementSystemEmergencyDC48VCurrent; + currentBusState["HVBBFCSSecurSysCur_uint16"] = state.bus3State.fuelCellSecuritySystemEmergencyDC48VCurrent; + currentBusState["HVBBplcCur_uint16"] = state.bus3State.plcControlPowerCurrent; + + currentBusState["LVBinsBusVol_uint16"] = state.bus4State.instrumentBusbarVoltage; + currentBusState["LVBBinsBusCur_uint16"] = state.bus4State.instrumentBusbarCurrent; + currentBusState["LVBBunit1Cur_uint16"] = state.bus4State.unit1Current; + currentBusState["LVBBunit2Cur_uint16"] = state.bus4State.unit2Current; + currentBusState["LVBBunit3Cur_uint16"] = state.bus4State.unit3Current; + currentBusState["LVBBunit5Cur_uint16"] = state.bus4State.unit5Current; + currentBusState["LVBBbowPZDevCur_uint16"] = state.bus4State.bowPZDeviceCurrent; + currentBusState["LVBBemerBatCur_uint16"] = state.bus4State.emergencyLithiumBatteryGroup1Current; + currentBusState["LVBBemerBusVol_uint16"] = state.bus4State.emergency1BusbarVoltage; + + // 转化为json格式 + + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; + return Json::writeString(writerBuilder, currentBusState); + } +}; + +#endif diff --git a/src/pPowerManger/msg/uPower_disSysState.h b/src/pPowerManger/msg/uPower_disSysState.h new file mode 100644 index 0000000..58e2cb7 --- /dev/null +++ b/src/pPowerManger/msg/uPower_disSysState.h @@ -0,0 +1,55 @@ +#ifndef U_POWER_DISSYSSTATE_ST_H +#define U_POWER_DISSYSSTATE_ST_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include +#include "../pmSysvariable.h" + +class uPower_disSysStateMsg +{ +private: + /* data */ +public: + uPower_disSysStateMsg() { + }; + ~uPower_disSysStateMsg() {}; + std::string key = "uPower_disSysState_st"; + + disSysBreakerList currentDisBreakerState; + + std::string buildMsg(disSysBreakerList currentDisBreakerState) + { + //构建配电系统状态报告 + Json::Value dis; + disBus1Breaker* pdis1=new disBus1Breaker; + disBus2Breaker* pdis2=new disBus2Breaker; + disBus3Breaker* pdis3=new disBus3Breaker; + disBus4Breaker* pdis4=new disBus4Breaker; + + *pdis1 = currentDisBreakerState.bus1Breaker; + *pdis2 = currentDisBreakerState.bus2Breaker; + *pdis3 = currentDisBreakerState.bus3Breaker; + *pdis4 = currentDisBreakerState.bus4Breaker; + + dis["HVolBusBreaker_uint16"] = *(unsigned short*)pdis1; + dis["HVolABusBreaker_unit16"] = *(unsigned short*)pdis2; + dis["HVolBBusBreaker_unit16"] = *(unsigned short*)pdis3; + dis["LVolBusBreaker_uint16"] = *(unsigned short*)pdis4; + + //TODO: 构建配电系统故障码 + // Json::Value faultCodeDis_array; + // for(auto val : m_pm->faultCode) + // { + // faultCodeDis_array.append(val); + // } + // dis[VAR_TO_STR(faultCode_array)] = faultCodeDis_array; + // 转化为json格式 + + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; + return Json::writeString(writerBuilder, dis); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_equInsState.h b/src/pPowerManger/msg/uPower_equInsState.h new file mode 100644 index 0000000..4d7b962 --- /dev/null +++ b/src/pPowerManger/msg/uPower_equInsState.h @@ -0,0 +1,220 @@ +#ifndef U_POWER_EQUINSSTATE_H +#define U_POWER_EQUINSSTATE_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include +class uPower_equInsStateMsg +{ +private: + /* data */ +public: + uPower_equInsStateMsg() { + // 初始化成员变量 + //state全部初始化为0 + memset(&state, 0, sizeof(state)); + }; // 添加默认构造函数实现 + ~uPower_equInsStateMsg() {}; // 添加析构函数实现 + std::string key = "uPower_equInsState_fb"; + + struct SensorState + { + unsigned int singleBeamSonar1 : 1; // 单波束声呐1 + unsigned int singleBeamSonar2 : 1; // 单波束声呐2 + unsigned int singleBeamSonar3 : 1; // 单波束声呐3 + unsigned int singleBeamSonar4 : 1; // 单波束声呐4 + unsigned int singleBeamSonar5 : 1; // 单波束声呐5 + unsigned int singleBeamSonar6 : 1; // 单波束声呐6 + unsigned int singleBeamSonar7 : 1; // 单波束声呐7 + unsigned int singleBeamSonar8 : 1; // 单波束声呐8 + unsigned int forwardSonar : 1; // 前视声呐 + unsigned int ctd1 : 1; // CTD1 + unsigned int ctd2 : 1; // CTD2 + unsigned int soundVelocityMeter : 1; // 声速仪 + unsigned int ntp : 1; // 深度计 + unsigned int depthMeter1 : 1; // 深度计1 + unsigned int depthMeter2 : 1; // 深度计2 + unsigned int depthMeter3 : 1; // 深度计3 + }; + struct ActuatorState + { + unsigned int openCloseMechanism1 : 1; // bit 0 启闭机构1 + unsigned int openCloseMechanism2 : 1; // bit 1 启闭机构2 + unsigned int openCloseMechanism3 : 1; // bit 2 启闭机构3 + unsigned int openCloseMechanism4 : 1; // bit 3 启闭机构4 + unsigned int openCloseMechanism5 : 1; // bit 4 启闭机构5 + unsigned int openCloseMechanism6 : 1; // bit 5 启闭机构6 + unsigned int reserved1 : 2; // bit 6-7 保留 + unsigned int openWaterMechanism1 : 1; // bit 8 敞水机构1 + unsigned int openWaterMechanism2 : 1; // bit 9 敞水机构2 + unsigned int openWaterMechanism3 : 1; // bit 10 敞水机构3 + unsigned int openWaterMechanism4 : 1; // bit 11 敞水机构4 + unsigned int openWaterMechanism5 : 1; // bit 12 敞水机构5 + unsigned int openWaterMechanism6 : 1; // bit 13 敞水机构6 + unsigned int openWaterMechanism7 : 1; // bit 14 敞水机构7 + unsigned int openWaterMechanism8 : 1; // bit 15 敞水机构8 + }; + + struct MotionState + { + unsigned int sternRudder1 : 1; // bit 0 艉部舵机1 + unsigned int sternRudder2 : 1; // bit 1 艉部舵机2 + unsigned int sternRudder3 : 1; // bit 2 艉部舵机3 + unsigned int sternRudder4 : 1; // bit 3 艉部舵机4 + unsigned int bowRudder : 1; // bit 4 艏舵电缸 + unsigned int waterInjection : 1; // bit 5 注水机构 + unsigned int propulsionMotor : 1; // bit 6 推进电机 + unsigned int buoyancyAdjust1 : 1; // bit 7 浮调机构(艏部)1 + unsigned int buoyancyAdjust2 : 1; // bit 8 浮调机构(艏部)2 + unsigned int buoyancyAdjust3 : 1; // bit 9 浮调机构(艏部)3 + unsigned int buoyancyAdjust4 : 1; // bit 10 浮调机构(艉部)4 + unsigned int buoyancyAdjust5 : 1; // bit 11 浮调机构(艉部)5 + unsigned int DVL : 1; // bit 12 DVL + unsigned int INS : 1; // bit 13 惯导系统 + unsigned int bowRudderLeft : 1; // bit 14 艏舵左舵机 + unsigned int bowRudderRight : 1; // bit 15 艏右舵舵机 + }; + struct LoadcommState + { + unsigned int payloadControl : 1; // bit 0 载荷发控 + unsigned int optMast : 1; // bit 1 光电桅杆 + unsigned int emMast : 1; // bit 2 电磁桅杆 + unsigned int reserved1 : 1; // bit 3 保留 + unsigned int sideSonar : 1; // bit 4 舷侧声纳 + unsigned int towedSonar : 1; // bit 5 拖曳声纳 + unsigned int reserved2 : 2; // bit 6-7 保留 + unsigned int commMast : 1; // bit 8 通信桅杆 + unsigned int midLowFreqSonar : 1; // bit 9 中低频声呐 + unsigned int highFreqComm : 1; // bit 10 高频声通机 + unsigned int buoySystem : 1; // bit 11 浮标系统 + unsigned int commMastRudder : 1; // bit 12 通信桅杆舵机 + unsigned int optMastRudder : 1; // bit 13 光电桅杆舵机 + unsigned int emMastRudder : 1; // bit 14 电磁桅杆舵机 + unsigned int reserved3 : 1; // bit 15 保留 + }; + struct ThrowPowerState + { + unsigned int bowThrow : 1; // bit 0 艏部抛载 + unsigned int reserved1 : 7; // bit 1-7 保留 + unsigned int fuelCellController : 1; // bit 8 燃料电池控制器 + unsigned int instrumentPanel : 1; // bit 9 仪表配电板 + unsigned int powerPanel : 1; // bit 10 动力配电板 + unsigned int instrumentBattery : 1; // bit 11 仪表锂电池 + unsigned int powerBattery : 1; // bit 12 动力锂电 + unsigned int sternThrow : 1; // bit 13 艉部抛载 + unsigned int reserved2 : 2; // bit 14-15 保留 + }; + struct uPower_equInsState + { + SensorState sensorState; + ActuatorState actuatorState; + MotionState motionState; + LoadcommState loadcommState; + ThrowPowerState throwPowerState; + } state; + std::string buildMsg(DriverTable s) + { + // 按照协议格式填充数据 + + // 传感器状态赋值 + state.sensorState.singleBeamSonar1 = s.singleBeamSonar1; + state.sensorState.singleBeamSonar2 = s.singleBeamSonar2; + state.sensorState.singleBeamSonar3 = s.singleBeamSonar3; + state.sensorState.singleBeamSonar4 = s.singleBeamSonar4; + state.sensorState.singleBeamSonar5 = s.singleBeamSonar5; + state.sensorState.singleBeamSonar6 = s.singleBeamSonar6; + state.sensorState.singleBeamSonar7 = s.singleBeamSonar7; + state.sensorState.singleBeamSonar8 = s.singleBeamSonar8; + state.sensorState.forwardSonar = s.forwardSonar; + state.sensorState.ctd1 = s.ctd1; + state.sensorState.ctd2 = s.ctd2; + state.sensorState.soundVelocityMeter = s.soundVeloc; + state.sensorState.ntp = s.ntp; + state.sensorState.depthMeter1 = s.depth1; + state.sensorState.depthMeter2 = s.depth2; + state.sensorState.depthMeter3 = s.depth3; + + // 执行机构状态赋值 + state.actuatorState.openCloseMechanism1 = s.bowCover1; + state.actuatorState.openCloseMechanism2 = s.bowCover2; + state.actuatorState.openCloseMechanism3 = s.bowCover3; + state.actuatorState.openCloseMechanism4 = s.bowCover4; + state.actuatorState.openCloseMechanism5 = s.bowCover5; + state.actuatorState.openCloseMechanism6 = s.bowCover6; + state.actuatorState.openWaterMechanism1 = s.bowWaterlnet1; + state.actuatorState.openWaterMechanism2 = s.bowWaterlnet2; + state.actuatorState.openWaterMechanism3 = s.bowWaterlnet3; + state.actuatorState.openWaterMechanism4 = s.bowWaterlnet4; + state.actuatorState.openWaterMechanism5 = s.bowWaterlnet5; + state.actuatorState.openWaterMechanism6 = s.bowWaterlnet6; + state.actuatorState.openWaterMechanism7 = s.bowWaterlnet7; + state.actuatorState.openWaterMechanism8 = s.bowWaterlnet8; + + // 运动状态赋值 + state.motionState.sternRudder1 = s.sternRudderServo1; + state.motionState.sternRudder2 = s.sternRudderServo2; + state.motionState.sternRudder3 = s.sternRudderServo3; + state.motionState.sternRudder4 = s.sternRudderServo4; + + state.motionState.bowRudder = s.bowRudderDeploy; + + state.motionState.waterInjection = s.waterInject; + + state.motionState.propulsionMotor = s.thruster; + state.motionState.buoyancyAdjust1 = s.buoyancyAdjust1; + state.motionState.buoyancyAdjust2 = s.buoyancyAdjust2; + state.motionState.buoyancyAdjust3 = s.buoyancyAdjust3; + state.motionState.buoyancyAdjust4 = s.buoyancyAdjust4; + state.motionState.buoyancyAdjust5 = s.buoyancyAdjust5; + state.motionState.DVL = s.DVL; + state.motionState.INS = s.ins; + + state.motionState.bowRudderLeft = s.bowRudderServo1; + state.motionState.bowRudderRight = s.bowRudderServo2; + + // 负载通信状态赋值 + state.loadcommState.payloadControl = s.launchControler; + state.loadcommState.sideSonar = s.sideSonar; + state.loadcommState.optMast = s.photoSensor; + state.loadcommState.emMast = s.electSensor; + state.loadcommState.buoySystem = s.buoyage; + state.loadcommState.commMastRudder = s.mastLiftingServo; + state.loadcommState.optMastRudder = s.mastLiftingServo; + state.loadcommState.emMastRudder = s.mastLiftingServo; + state.loadcommState.highFreqComm = s.USBL; + state.loadcommState.midLowFreqSonar = s.lowFreqSonar; + state.loadcommState.commMast = s.commMast; + state.loadcommState.towedSonar = 0; //拖曳声纳未安装,默认为0 + + // 抛载和电源状态赋值 + state.throwPowerState.bowThrow = s.bowThrow; // 艏部抛载 + state.throwPowerState.sternThrow = s.sternThrow; // 艉部抛载 + state.throwPowerState.fuelCellController = 1; // 燃料电池控制器 默认开启 + state.throwPowerState.instrumentPanel = 1; // 仪表配电板 默认开启 + state.throwPowerState.powerPanel = 1; // 动力配电板 默认开启 + state.throwPowerState.instrumentBattery = 1; // 仪表锂电池 默认开启 + state.throwPowerState.powerBattery = 1; // 动力锂电 默认开启 + + // 转化为json格式 + Json::Value root; + root["sensor_int16"] = *reinterpret_cast(&state.sensorState); + root["actuator_int16"] = *reinterpret_cast(&state.actuatorState); + root["motion_int16"] = *reinterpret_cast(&state.motionState); + root["loadcomm_int16"] = *reinterpret_cast(&state.loadcommState); + root["throwpower_int16"] = *reinterpret_cast(&state.throwPowerState); + + //以二进制形式打印 + // std::cout << "sensor_int16: " << std::bitset<16>(*reinterpret_cast(&state.sensorState)) << std::endl; + // std::cout << "actuator_int16: " << std::bitset<16>(*reinterpret_cast(&state.actuatorState)) << std::endl; + // std::cout << "motion_int16: " << std::bitset<16>(*reinterpret_cast(&state.motionState)) << std::endl; + // std::cout << "loadcomm_int16: " << std::bitset<16>(*reinterpret_cast(&state.loadcommState)) << std::endl; + // std::cout << "throwpower_int16: " << std::bitset<16>(*reinterpret_cast(&state.throwPowerState)) << std::endl; + + // 返回json字符串 + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; // 紧凑格式,无缩进 + return Json::writeString(writerBuilder, root); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_equState.h b/src/pPowerManger/msg/uPower_equState.h new file mode 100644 index 0000000..78035e6 --- /dev/null +++ b/src/pPowerManger/msg/uPower_equState.h @@ -0,0 +1,26 @@ +#ifndef U_POWER_EQUSTATE_FB_H +#define U_POWER_EQUSTATE_FB_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include + +class uPower_equStateMsg +{ +private: + /* data */ +public: + uPower_equStateMsg() { + }; + ~uPower_equStateMsg() {}; + std::string key = "uPower_equState_fb"; + + Driver driver; + + std::string buildMsg(DriverTable s) + { + return driver.saveDriverTableToJson(&s); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_fcsState.h b/src/pPowerManger/msg/uPower_fcsState.h new file mode 100644 index 0000000..5913c57 --- /dev/null +++ b/src/pPowerManger/msg/uPower_fcsState.h @@ -0,0 +1,133 @@ +#ifndef U_POWER_FCSSTATE_ST_H +#define U_POWER_FCSSTATE_ST_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include + +class uPower_fcsStateMsg +{ +private: + /* data */ +public: + uPower_fcsStateMsg() { + memset(&state, 0, sizeof(state)); + }; + ~uPower_fcsStateMsg() {}; + std::string key = "uPower_fcsState_st"; + + struct uPower_fcsState + { + unsigned int fcsStatus : 4; // 燃料电池状态 + unsigned int outputPower : 12; // 输出功率 (0-4095) + unsigned int temperature : 8; // 温度 (0-255) + unsigned int errorCode : 8; // 错误代码 + } state; + + std::string buildMsg(ccuState ccustate) + { + //TODO:根据最新协议修改 + Json::Value fcs; + // suffix = getTypeName(typeid(ccustate.fcuState).name()); + // fcs["fcuState"] = ccustate.fcuState; + + // suffix = getTypeName(typeid(ccustate.fcuFaultLeve).name()); + // fcs["fcuFaultLeve"] = ccustate.fcuFaultLeve; + + // suffix = getTypeName(typeid(ccustate.powerLimit).name()); + // fcs[VAR_TO_STR(powLimit)+suffix] = ccustate.powerLimit; + + // suffix = getTypeName(typeid(ccustate.totalPowerGeneration).name()); + // fcs[VAR_TO_STR(powerGen)+suffix] = ccustate.totalPowerGeneration; + + // suffix = getTypeName(typeid(ccustate.ch4o).name()); + // fcs[VAR_TO_STR(ch4o)+suffix] = ccustate.ch4o; + + // suffix = getTypeName(typeid(ccustate.o2).name()); + // fcs[VAR_TO_STR(o2)+suffix] = ccustate.o2; + + // suffix = getTypeName(typeid(ccustate.fcuVoltage).name()); + // fcs[VAR_TO_STR(fcuVol)+suffix] = ccustate.fcuVoltage; + + // suffix = getTypeName(typeid(ccustate.fcuCurrent).name()); + // fcs[VAR_TO_STR(fcuCur)+suffix] = ccustate.fcuCurrent; + + // suffix = getTypeName(typeid(ccustate.o2Level).name()); + // fcs[VAR_TO_STR(o2Level)+suffix] = ccustate.o2Level; + + // suffix = getTypeName(typeid(ccustate.exchangerTemperature).name()); + // fcs[VAR_TO_STR(excTemp)+suffix] = ccustate.exchangerTemperature; + + // suffix = getTypeName(typeid(ccustate.fcuOutPower).name()); + // fcs[VAR_TO_STR(fcuOutPower)+suffix] = ccustate.fcuOutPower; + + // suffix = getTypeName(typeid(ccustate.fcuOutIns).name()); + // fcs[VAR_TO_STR(fcuOutIns)+suffix] = ccustate.fcuOutIns; + + // suffix = getTypeName(typeid(ccustate.fcuVoltageIns).name()); + // fcs[VAR_TO_STR(fcuVolIns)+suffix] = ccustate.fcuVoltageIns; + + // suffix = getTypeName(typeid(ccustate.fcuVoltagePower).name()); + // fcs[VAR_TO_STR(fcuVolPower)+suffix] = ccustate.fcuVoltagePower; + + // suffix = getTypeName(typeid(ccustate.fcuCurrentIns).name()); + // fcs[VAR_TO_STR(fcuCurIns)+suffix] = ccustate.fcuCurrentIns; + + // suffix = getTypeName(typeid(ccustate.fcuCurrentPower).name()); + // fcs[VAR_TO_STR(fcuCurPower)+suffix] = ccustate.fcuCurrentPower; + + // suffix = getTypeName(typeid(ccustate.h2Concentration1).name()); + // fcs[VAR_TO_STR(h2Concent1)+suffix] = ccustate.h2Concentration1; + + // suffix = getTypeName(typeid(ccustate.h2Concentration2).name()); + // fcs[VAR_TO_STR(h2Concent2)+suffix] = ccustate.h2Concentration2; + + // suffix = getTypeName(typeid(ccustate.o2Concentration1).name()); + // fcs[VAR_TO_STR(o2Concent1)+suffix] = ccustate.o2Concentration1; + + // suffix = getTypeName(typeid(ccustate.o2Concentration2).name()); + // fcs[VAR_TO_STR(o2Concent2)+suffix] = ccustate.o2Concentration2; + + // suffix = getTypeName(typeid(ccustate.ch4oConcentration1).name()); + // fcs[VAR_TO_STR(ch4oConcent1)+suffix] = ccustate.ch4oConcentration1; + + // suffix = getTypeName(typeid(ccustate.ch4oConcentration2).name()); + // fcs[VAR_TO_STR(ch4oConcent2)+suffix] = ccustate.ch4oConcentration2; + + // suffix = getTypeName(typeid(ccustate.backpressure1).name()); + // fcs[VAR_TO_STR(backpressure1)+suffix] = ccustate.backpressure1; + + // suffix = getTypeName(typeid(ccustate.backpressure2).name()); + // fcs[VAR_TO_STR(backpressure2)+suffix] = ccustate.backpressure2; + + // suffix = getTypeName(typeid(ccustate.flameDetection).name()); + // fcs[VAR_TO_STR(flameDet)+suffix] = ccustate.flameDetection; + + // unsigned short faultCode1; + // unsigned short faultCode2; + // unsigned short faultCode3; + // faultCode1 = (ccustate.fcuGZ_1H << 8) | ccustate.fcuGZ_1L; + // faultCode2 = (ccustate.fcuGZ_2H << 8) | ccustate.fcuGZ_2L; + // faultCode3 = (ccustate.fcuGZ_3H << 8) | ccustate.fcuGZ_3L; + + // suffix = getTypeName(typeid(faultCode1).name()); + // fcs[VAR_TO_STR(faultCode1)+suffix] = faultCode1; + // suffix = getTypeName(typeid(faultCode2).name()); + // fcs[VAR_TO_STR(faultCode2)+suffix] = faultCode2; + // suffix = getTypeName(typeid(faultCode3).name()); + // fcs[VAR_TO_STR(faultCode3)+suffix] = faultCode3; + + // // 转化为json格式 + // Json::Value root; + // root["fcsStatus"] = state.fcsStatus; + // root["outputPower"] = state.outputPower; + // root["temperature"] = state.temperature; + // root["errorCode"] = state.errorCode; + + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; + return Json::writeString(writerBuilder, fcs); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_liBatState.h b/src/pPowerManger/msg/uPower_liBatState.h new file mode 100644 index 0000000..b19e437 --- /dev/null +++ b/src/pPowerManger/msg/uPower_liBatState.h @@ -0,0 +1,137 @@ +#ifndef U_POWER_LIBATSTATE_ST_H +#define U_POWER_LIBATSTATE_ST_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include + +class uPower_liBatStateMsg +{ +private: + /* data */ +public: + uPower_liBatStateMsg() { + }; + ~uPower_liBatStateMsg() {}; + std::string key = "uPower_liBatState_st"; + + + std::string buildMsg(ccuState ccustate) + { + //TODO:根据最新协议修改 + Json::Value lbs; + //构建动力锂电池状态报告 + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPosRelayState).name()); + // lbs[VAR_TO_STR(insPosRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.insPosRelayState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insNegRelayState).name()); + // lbs[VAR_TO_STR(insNegRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.insNegRelayState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPosRelayState).name()); + // lbs[VAR_TO_STR(powPosRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPosRelayState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerNegRelayState).name()); + // lbs[VAR_TO_STR(powNegRelayState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerNegRelayState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatLimit).name()); + // lbs[VAR_TO_STR(insBatLimit)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatLimit; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatLimit).name()); + // lbs[VAR_TO_STR(powerBatLimit)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatLimit; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatSoc).name()); + // lbs[VAR_TO_STR(insBatSoc)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatSoc; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatSoc).name()); + // lbs[VAR_TO_STR(powBatSoc)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatSoc; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatTotalElectricity).name()); + // lbs[VAR_TO_STR(insBatTotalElect)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatTotalElectricity; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatTotalElectricity).name()); + // lbs[VAR_TO_STR(powBatTotalElect)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatTotalElectricity; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insBatCurrentElectricity).name()); + // lbs[VAR_TO_STR(insBatCurElect)+suffix] = m_pm->m_pmCurrentState.ccustate.insBatCurrentElectricity; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerBatCurrentElectricity).name()); + // lbs[VAR_TO_STR(powBatCurElect)+suffix] = m_pm->m_pmCurrentState.ccustate.powerBatCurrentElectricity; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insChargeState).name()); + // lbs[VAR_TO_STR(insChargeState)+suffix] = m_pm->m_pmCurrentState.ccustate.insChargeState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerChargeState).name()); + // lbs[VAR_TO_STR(powChargeState)+suffix] = m_pm->m_pmCurrentState.ccustate.powerChargeState; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insLinkVoltage).name()); + // lbs[VAR_TO_STR(insLinkVol)+suffix] = m_pm->m_pmCurrentState.ccustate.insLinkVoltage; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPackVoltage).name()); + // lbs[VAR_TO_STR(insPackVol)+suffix] = m_pm->m_pmCurrentState.ccustate.insPackVoltage; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrent).name()); + // lbs[VAR_TO_STR(insCurrent)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrent; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insPosInsulationResistance).name()); + // lbs[VAR_TO_STR(insPosRes)+suffix] = m_pm->m_pmCurrentState.ccustate.insPosInsulationResistance; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insNegInsulationResistance).name()); + // lbs[VAR_TO_STR(insNegRes)+suffix] = m_pm->m_pmCurrentState.ccustate.insNegInsulationResistance; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerLinkVoltage).name()); + // lbs[VAR_TO_STR(powLinkVol)+suffix] = m_pm->m_pmCurrentState.ccustate.powerLinkVoltage; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPackVoltage).name()); + // lbs[VAR_TO_STR(powerPackVol)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPackVoltage; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrent).name()); + // lbs[VAR_TO_STR(powCur)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrent; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerPosInsulationResistance).name()); + // lbs[VAR_TO_STR(powPosRes)+suffix] = m_pm->m_pmCurrentState.ccustate.powerPosInsulationResistance; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerNegInsulationResistance).name()); + // lbs[VAR_TO_STR(powNegRes)+suffix] = m_pm->m_pmCurrentState.ccustate.powerNegInsulationResistance; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold1).name()); + // lbs[VAR_TO_STR(insCurSocHold1)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold1; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold2).name()); + // lbs[VAR_TO_STR(insCurSocHold2)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold2; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insCurrentSocHold3).name()); + // lbs[VAR_TO_STR(insCurSocHold3)+suffix] = m_pm->m_pmCurrentState.ccustate.insCurrentSocHold3; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentToInsLimit1).name()); + // lbs[VAR_TO_STR(fcuCurToInsLimit1)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentToInsLimit1; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.fcuCurrentToinsLimit2).name()); + // lbs[VAR_TO_STR(fcuCurToinsLimit2)+suffix] = m_pm->m_pmCurrentState.ccustate.fcuCurrentToinsLimit2; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold1).name()); + // lbs[VAR_TO_STR(powCurSocHold1)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold1; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold2).name()); + // lbs[VAR_TO_STR(powCurSocHold2)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold2; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold3).name()); + // lbs[VAR_TO_STR(powCurSocHold3)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentSocHold3; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentToInsLimit1).name()); + // lbs[VAR_TO_STR(powCurToInsLimit1)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentToInsLimit1; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerCurrentToinsLimit2).name()); + // lbs[VAR_TO_STR(powCurToinsLimit2)+suffix] = m_pm->m_pmCurrentState.ccustate.powerCurrentToinsLimit2; + + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.insAlarmIdentificationWord).name()); + // lbs[VAR_TO_STR(insfaultCode)+suffix] = m_pm->m_pmCurrentState.ccustate.insAlarmIdentificationWord; + // suffix = getTypeName(typeid(m_pm->m_pmCurrentState.ccustate.powerAlarmIdentificationWord).name()); + // lbs[VAR_TO_STR(powfaultCode)+suffix] = m_pm->m_pmCurrentState.ccustate.powerAlarmIdentificationWord; + + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; + return Json::writeString(writerBuilder, lbs); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/msg/uPower_pmState.h b/src/pPowerManger/msg/uPower_pmState.h new file mode 100644 index 0000000..81d9b45 --- /dev/null +++ b/src/pPowerManger/msg/uPower_pmState.h @@ -0,0 +1,63 @@ +#ifndef U_POWER_PMSTATE_FB_H +#define U_POWER_PMSTATE_FB_H +#include "../driver.h" +#include "string" +#include "json/json.h" +#include + +class uPower_pmStateMsg +{ +private: + /* data */ +public: + uPower_pmStateMsg() { + memset(&state, 0, sizeof(state)); + }; + ~uPower_pmStateMsg() {}; + std::string key = "uPower_pmState_fb"; + + struct uPower_pmState + { + unsigned char workCondition; + unsigned char currentMod; + unsigned char powerState; + unsigned char faultLevel; + vector faultCode; + unsigned int soc; + unsigned int sustainableTime; + unsigned int m_faultNum; + unsigned char m_leakage; + } state; + + std::string buildMsg() + { + // 状态赋值 + //1.构建系统状态报告 + Json::Value pms; + + pms["workCondition_uint"] = state.workCondition; + pms["currentMod_uint8"] = state.currentMod; + pms["powerState_uint8"] = state.powerState; + pms["faultLevel_uint8"] = state.faultLevel; + + Json::Value faultCode_array; + for(auto val : state.faultCode) + { + faultCode_array.append(val); + } + pms["faultCode_array"] = faultCode_array; + + pms["soc_uint16"] = state.soc; + + pms["sustainableTime_int64"] = state.sustainableTime; + + pms["leakage_uint8"] = state.m_leakage; + + // 转化为json格式 + Json::StreamWriterBuilder writerBuilder; + writerBuilder.settings_["indentation"] = ""; + return Json::writeString(writerBuilder, pms); + } +}; + +#endif \ No newline at end of file diff --git a/src/pPowerManger/pmSysvariable.h b/src/pPowerManger/pmSysvariable.h index 4661b8e..ef04513 100644 --- a/src/pPowerManger/pmSysvariable.h +++ b/src/pPowerManger/pmSysvariable.h @@ -10,87 +10,106 @@ #define BREAK_ON 0x55 #define BREAK_FALSE 0x5A - - //消息结构体变量定义 #pragma pack (1) typedef struct ccuState { - unsigned char currentWorkCondition; - unsigned char fcuState; - unsigned char fcuFaultLeve; - float powerLimit; - float totalPowerGeneration; - float ch4o; - float o2; - float fcuVoltage; - float fcuCurrent; - float o2Level; - float placeholder1; - float exchangerTemperature; - float fcuOutPower; - float fcuOutIns; - float fcuVoltageIns; - float fcuVoltagePower; - float fcuCurrentIns; - float fcuCurrentPower; - float h2Concentration1; - float h2Concentration2; - float o2Concentration1; - float o2Concentration2; - float ch4oConcentration1; - float ch4oConcentration2; - float backpressure1; - float backpressure2; - unsigned char flameDetection; - unsigned char fcuGZ_1L; - unsigned char fcuGZ_1H; - unsigned char fcuGZ_2L; - unsigned char fcuGZ_2H; - unsigned char fcuGZ_3L; - unsigned char fcuGZ_3H; - unsigned char insPosRelayState; - unsigned char insNegRelayState; - unsigned char powerPosRelayState; - unsigned char powerNegRelayState; - unsigned short insBatLimit; - unsigned short powerBatLimit; - unsigned char insBatSoc; - unsigned char powerBatSoc; - unsigned short insBatTotalElectricity; - unsigned short powerBatTotalElectricity; - unsigned short insBatCurrentElectricity; - unsigned short powerBatCurrentElectricity; - unsigned char insChargeState; - unsigned char powerChargeState; - unsigned short insLinkVoltage; - unsigned short insPackVoltage; - unsigned short insCurrent; - unsigned short insPosInsulationResistance; - unsigned short insNegInsulationResistance; - unsigned short powerLinkVoltage; - unsigned short powerPackVoltage; - unsigned short powerCurrent; - unsigned short powerPosInsulationResistance; - unsigned short powerNegInsulationResistance; - unsigned char insEmergencyStatusWord; - unsigned char powerEmergencyStatusWord; - unsigned char insAlarmIdentificationWord; - unsigned char powerAlarmIdentificationWord; - unsigned char insCurrentSocHold1; - unsigned char insCurrentSocHold2; - unsigned char insCurrentSocHold3; - unsigned char fcuCurrentToInsLimit1; - unsigned char fcuCurrentToinsLimit2; - unsigned char powerCurrentSocHold1; - unsigned char powerCurrentSocHold2; - unsigned char powerCurrentSocHold3; - unsigned char powerCurrentToInsLimit1; - unsigned char powerCurrentToinsLimit2; - float placeholder2; - float placeholder3; - float placeholder4; - float placeholder5; + uint8_t fc_mode; // 燃料电池系统运行模式:00H-无效, 01H-调试, 02H-自动, 03H-补给 + uint8_t fc_status; // 燃料电池状态:00H-无效, 01H-初始化, ..., 0DH-维护完成(详见协议) + uint8_t fc_fault_level; // 燃料电池故障等级:00H-无故障, 10H-一级, 20H-二级, 30H-三级, 40H-四级 + + uint16_t output_power_limit; // 系统输出功率限制值,单位:W,范围:0~30000W + uint16_t total_generation_time; // 系统累计发电时间,单位:0.1小时,最大值6553.5小时 + uint16_t total_generation_power; // 系统累计发电总功率,单位:W + uint16_t fault_level_1; // 一级故障位,按位表示不同的故障项 + uint16_t fault_level_2; // 二级故障位 + uint16_t fault_level_3; // 三级故障位 + uint16_t fault_level_4; // 四级故障位 + + uint8_t hydrogen_capacity; // 储氢罐剩余容量百分比,单位:%,范围:0~100 + uint8_t liquid_oxygen_capacity; // 液氧罐剩余容量百分比,单位:%,范围:0~100 + + uint16_t palladium_temp; // 钯膜最高温度,单位:℃ + uint16_t main_pipe_pressure; // 主水路压力,单位:0.01kPa + uint16_t aux_pipe_pressure; // 辅水路压力,单位:0.01kPa + + uint16_t cabin_pressure1; // 舱室1压力,单位:0.01kPa + uint16_t cabin_pressure2; // 舱室2压力,单位:0.01kPa + uint16_t cabin_temp1; // 舱室1温度,单位:0.01℃ + uint16_t cabin_temp2; // 舱室2温度,单位:0.01℃ + uint16_t cabin_humidity1; // 舱室1湿度,单位:0.01%RH + uint16_t cabin_humidity2; // 舱室2湿度,单位:0.01%RH + + uint8_t flame_detector1; // 火焰探测器1状态:00H-无效, 01H-报警, 02H-故障 + uint8_t flame_detector2; // 火焰探测器2状态:00H-无效, 01H-报警, 02H-故障 + + uint16_t h2_concentration1; // 舱室H2浓度1,单位:0.01% LEL(爆炸下限) + uint16_t h2_concentration2; // 舱室H2浓度2,单位:0.01% LEL + uint16_t h2_concentration3; // 舱室H2浓度3,单位:0.01% LEL + uint16_t o2_concentration1; // 舱室O2浓度1,单位:0.01% LEL + uint16_t o2_concentration2; // 舱室O2浓度2,单位:0.01% LEL + uint16_t ch3oh_concentration1; // 舱室甲醇气体浓度1,单位:0.01% LEL + uint16_t ch3oh_concentration2; // 舱室甲醇气体浓度2,单位:0.01% LEL + + uint16_t reserved1[18]; // 保留字段,地址范围35~52,共18个uint16_t,协议预留 + + uint8_t dyn_alarm_flag[6]; // 动力锂电池报警标志字数组,共6字节,按位表示各类报警 + uint8_t ins_alarm_flag[6]; // 仪表锂电池报警标志字数组,共6字节,按位表示各类报警 + + uint8_t ins_relay_status1; // 仪表电池继电器状态,高4位表示正极继电器,低4位表示充电继电器 + uint8_t ins_relay_status2; // 仪表电池预充继电器和负极继电器状态 + uint8_t dyn_relay_status1; // 动力电池正极与充电继电器状态 + uint8_t dyn_relay_status2; // 动力电池预充与负极继电器状态 + + uint16_t ins_max_discharge_power; // 仪表电池最大允许放电功率,单位:kW,精度0.05kW + uint16_t dyn_max_discharge_power; // 动力电池最大允许放电功率,单位:kW,精度0.05kW + + uint8_t ins_soc; // 仪表锂电池荷电状态SOC,范围:0~100 + uint8_t dyn_soc; // 动力锂电池荷电状态SOC,范围:0~100 + + uint16_t ins_total_energy; // 仪表电池总能量,单位:kWh + uint16_t dyn_total_energy; // 动力电池总能量,单位:kWh + + uint16_t ins_power_input; // 仪表电池输入功率,单位:kW + uint16_t dyn_power_input; // 动力电池输入功率,单位:kW + + uint8_t ins_charge_status; // 仪表电池充放电状态:00H-无效,10H-充电,20H-放电 + uint8_t dyn_charge_status; // 动力电池充放电状态:00H-无效,10H-充电,20H-放电 + + uint16_t ins_voltage_link; // 仪表电池LINK端电压,单位:0.01V + uint16_t ins_voltage_pack; // 仪表电池PACK端电压,单位:0.01V + uint16_t ins_current; // 仪表电池电流,单位:0.01A(正值放电) + uint16_t ins_resistance_pos; // 仪表电池正极绝缘电阻,单位:kΩ + uint16_t ins_resistance_neg; // 仪表电池负极绝缘电阻,单位:kΩ + + uint16_t dyn_voltage_link; // 动力电池LINK端电压,单位:0.01V + uint16_t dyn_voltage_pack; // 动力电池PACK端电压,单位:0.01V + uint16_t dyn_current; // 动力电池电流,单位:0.01A(正值放电) + uint16_t dyn_resistance_pos; // 动力电池正极绝缘电阻,单位:kΩ + uint16_t dyn_resistance_neg; // 动力电池负极绝缘电阻,单位:kΩ + + uint8_t ins_emergency_status; // 仪表电池紧急状态字,按位表示异常或告警状态 + uint8_t dyn_emergency_status; // 动力电池紧急状态字,按位表示异常或告警状态 + + uint8_t reserved2[2]; // 保留字节,协议预留 + + uint8_t ins_soc_threshold1; // 仪表电池1 SOC门限,范围:0~100 + uint8_t ins_soc_threshold2; // 仪表电池2 SOC门限,范围:0~100 + uint8_t ins_soc_threshold3; // 仪表电池3 SOC门限,范围:0~100 + uint8_t dyn_soc_threshold1; // 动力电池1 SOC门限,范围:0~100 + uint8_t dyn_soc_threshold2; // 动力电池2 SOC门限,范围:0~100 + uint8_t dyn_soc_threshold3; // 动力电池3 SOC门限,范围:0~100 + + uint8_t ins_power_limit1; // 仪表电池1功率限制值,单位:% + uint8_t ins_power_limit2; // 仪表电池2功率限制值,单位:% + uint8_t dyn_power_limit1; // 动力电池1功率限制值,单位:% + uint8_t dyn_power_limit2; // 动力电池2功率限制值,单位:% + + uint32_t device_online_flag1; // 设备在线状态标志1,byte0:低压配电板在线标志位 byte1:复合管控主机在线标志位 byte2:复合管控备机在线标志位 + uint32_t device_online_flag2; // 设备在线状态标志2,byte0:仪表锂电在线标志位 byte1:动力锂电在线标志位 byte2:燃电锂电在线标志位 byte3:高压配电板在线标志位 + + uint32_t reserved3; // 保留字段,协议预留 + uint32_t heartbeat; // 主机心跳计数器或标志值 } ccuState; typedef struct { @@ -116,6 +135,8 @@ typedef struct { unsigned char powerBatEfficiency; unsigned char heartbeat; unsigned char masterState; + unsigned int paceholder1; + unsigned int paceholder2; }ccuColCmd; typedef struct disHighVolBusState @@ -551,7 +572,8 @@ enum class FcuState : unsigned char { namespace BatteryCommand { enum Type : unsigned char { Start = 0x10, - Stop = 0x20 + Stop = 0x20, + Hold = 0x00 }; }; @@ -733,53 +755,53 @@ namespace DeviceId { namespace FaultEnable { enum Type : bool { - BasicNavigationFault_1 = true, // 使能故障 - BasicNavigationFault_2 = true, - BasicNavigationFault_3 = true, - BasicNavigationFault_4 = true, - BasicNavigationFault_5 = true, - BasicNavigationFault_6 = true, - BasicNavigationFault_7 = true, - BasicNavigationFault_8 = true, - BasicNavigationFault_9 = true, - BasicNavigationFault_10 = true, + BasicNavigationFault_1 = false, // 使能故障 + BasicNavigationFault_2 = false, + BasicNavigationFault_3 = false, + BasicNavigationFault_4 = false, + BasicNavigationFault_5 = false, + BasicNavigationFault_6 = false, + BasicNavigationFault_7 = false, + BasicNavigationFault_8 = false, + BasicNavigationFault_9 = false, + BasicNavigationFault_10 = false, - ExtendedNavigationFault_1 = true, // 使能故障 - ExtendedNavigationFault_2 = true, - ExtendedNavigationFault_3 = true, - ExtendedNavigationFault_4 = true, + ExtendedNavigationFault_1 = false, // 使能故障 + ExtendedNavigationFault_2 = false, + ExtendedNavigationFault_3 = false, + ExtendedNavigationFault_4 = false, - ObstacleAvoidanceFault_1 = true, // 使能故障 - ObstacleAvoidanceFault_2 = true, - ObstacleAvoidanceFault_3 = true, + ObstacleAvoidanceFault_1 = false, // 使能故障 + ObstacleAvoidanceFault_2 = false, + ObstacleAvoidanceFault_3 = false, - BuoyancyControlFault_1 = true, // 使能故障 - BuoyancyControlFault_2 = true, - BuoyancyControlFault_3 = true, - BuoyancyControlFault_4 = true, + BuoyancyControlFault_1 = false, // 使能故障 + BuoyancyControlFault_2 = false, + BuoyancyControlFault_3 = false, + BuoyancyControlFault_4 = false, - CommunicationSystemFault_1 = true, // 使能故障 - CommunicationSystemFault_2 = true, - CommunicationSystemFault_3 = true, + CommunicationSystemFault_1 = false, // 使能故障 + CommunicationSystemFault_2 = false, + CommunicationSystemFault_3 = false, - PayloadSystemFault_1 = true, // 使能故障 - PayloadSystemFault_2 = true, - PayloadSystemFault_3 = true, - PayloadSystemFault_4 = true, - PayloadSystemFault_5 = true, - PayloadSystemFault_6 = true, - PayloadSystemFault_7 = true, + PayloadSystemFault_1 = false, // 使能故障 + PayloadSystemFault_2 = false, + PayloadSystemFault_3 = false, + PayloadSystemFault_4 = false, + PayloadSystemFault_5 = false, + PayloadSystemFault_6 = false, + PayloadSystemFault_7 = false, - EmergencySystemFault_1 = true, // 使能故障 - EmergencySystemFault_2 = true, - EmergencySystemFault_3 = true, - EmergencySystemFault_4 = true, - EmergencySystemFault_5 = true, - EmergencySystemFault_6 = true, + EmergencySystemFault_1 = false, // 使能故障 + EmergencySystemFault_2 = false, + EmergencySystemFault_3 = false, + EmergencySystemFault_4 = false, + EmergencySystemFault_5 = false, + EmergencySystemFault_6 = false, - SensorSystemFault_1 = true, // 使能故障 - SensorSystemFault_2 = true, - SensorSystemFault_3 = true, + SensorSystemFault_1 = false, // 使能故障 + SensorSystemFault_2 = false, + SensorSystemFault_3 = false, }; } diff --git a/test/disSysTest.zip b/test/disSysTest.zip new file mode 100644 index 0000000000000000000000000000000000000000..09dec11651f614936d1bb48f6f6ff09ce7999323 GIT binary patch literal 61619 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

iHealJ-!Wy}0^b{9%& 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 50: + self.log_text.delete(1.0, 2.0) + self.log_text.config(state=tk.DISABLED) self.log_text.see(tk.END) diff --git a/test/disSysTest/db.py b/test/disSysTest/db.py index 4ba446b..aa2b93b 100644 --- a/test/disSysTest/db.py +++ b/test/disSysTest/db.py @@ -143,7 +143,8 @@ class DB: reservedCircuitBreaker1 INTEGER, reservedCircuitBreaker2 INTEGER, emergencyLithiumBatteryGroup1CircuitBreaker INTEGER, - powerFailureSignal INTEGER, + instrumentPowerFailureSignal INTEGER, + emergencyPowerFailureSignal INTEGER, waterIngressionAlarm INTEGER, instrumentBusbarVoltage INTEGER, instrumentBusbarCurrent INTEGER, @@ -369,7 +370,9 @@ class DB: 'reservedCircuitBreaker1': data.reservedCircuitBreaker1, 'reservedCircuitBreaker2': data.reservedCircuitBreaker2, 'emergencyLithiumBatteryGroup1CircuitBreaker': data.emergencyLithiumBatteryGroup1CircuitBreaker, - 'powerFailureSignal': data.powerFailureSignal, + # 'powerFailureSignal': data.powerFailureSignal, + 'instrumentPowerFailureSignal': data.instrumentPowerFailureSignal, + 'emergencyPowerFailureSignal': data.emergencyPowerFailureSignal, 'waterIngressionAlarm': data.waterIngressionAlarm, 'instrumentBusbarVoltage': data.instrumentBusbarVoltage, 'instrumentBusbarCurrent': data.instrumentBusbarCurrent, @@ -556,7 +559,9 @@ if __name__ == "__main__": fb4.reservedCircuitBreaker1 = 0 fb4.reservedCircuitBreaker2 = 0 fb4.emergencyLithiumBatteryGroup1CircuitBreaker = 1 - fb4.powerFailureSignal = 0 + # fb4.powerFailureSignal = 0 + fb4.instrumentPowerFailureSignal = 0 + fb4.emergencyPowerFailureSignal = 0 fb4.waterIngressionAlarm = 0 fb4.instrumentBusbarVoltage = 48 fb4.instrumentBusbarCurrent = 10 diff --git a/test/disSysTest/test.py b/test/disSysTest/test.py index 93d1398..5281f35 100644 --- a/test/disSysTest/test.py +++ b/test/disSysTest/test.py @@ -14,7 +14,7 @@ from udpMsg import ( ) class PowerManagerSimulator: - def __init__(self, host='127.0.0.1', port=5001): + def __init__(self, host='127.0.0.1', port=6000): self.host = host self.port = port self.running = False @@ -63,19 +63,19 @@ class PowerManagerSimulator: self.high_vol_fb.sternFTDevice45Current = 15 self.high_vol_fb.tyzReservedSwitchCurrent = 0 self.high_vol_fb.sternRudderSwitch1Current = 10 - self.high_vol_fb.reservedCurrent1 = 0 + self.high_vol_fb.reservedCurrent1 = 100 self.high_vol_fb.sternRudderSwitch2Current = 10 - self.high_vol_fb.reservedCurrent2 = 0 - self.high_vol_fb.fbReservedSwitchCurrent = 0 - self.high_vol_fb.reservedCurrent3 = 0 + self.high_vol_fb.reservedCurrent2 = 100 + self.high_vol_fb.fbReservedSwitchCurrent = 1000 + self.high_vol_fb.reservedCurrent3 = 100 self.high_vol_fb.coolWaterPressure = 100 # 高压A母线反馈数据 - 测试所有成员 - self.high_a_vol_fb.bowFTDevice123CircuitBreaker = 0x55 - self.high_a_vol_fb.actuatorCircuitBreaker = 0x55 - self.high_a_vol_fb.mastSteeringGearControlBoxCircuitBreaker = 0x55 - self.high_a_vol_fb.xczCircuitBreaker = 0x55 - self.high_a_vol_fb.bowRudderControlBoxCircuitBreaker = 0x55 + self.high_a_vol_fb.bowFTDevice123CircuitBreaker = 0x5A + self.high_a_vol_fb.actuatorCircuitBreaker = 0x5A + self.high_a_vol_fb.mastSteeringGearControlBoxCircuitBreaker = 0x5A + self.high_a_vol_fb.xczCircuitBreaker = 0x5A + self.high_a_vol_fb.bowRudderControlBoxCircuitBreaker = 0x5A self.high_a_vol_fb.openWaterCoverStartCylinderCircuitBreaker = 0x55 self.high_a_vol_fb.instrumentPowerFailureSignal = 0x55 self.high_a_vol_fb.emergencyPowerFailureSignal = 0x55 @@ -90,40 +90,41 @@ class PowerManagerSimulator: self.high_a_vol_fb.openWaterCoverStartCylinderCurrent = 0 # 仪表主母线反馈数据 - 测试所有成员 - self.low_main_fb.lithiumBatteryGroupInstrumentCircuitBreaker = 0x55 + self.low_main_fb.lithiumBatteryGroupInstrumentCircuitBreaker = 0x5A self.low_main_fb.bowLowVoltageDistributionBoxCircuitBreaker = 0x55 self.low_main_fb.unit4InstrumentDC48VCircuitBreaker = 0x55 - self.low_main_fb.dcC1DCDistributionPanelCircuitBreaker = 0x55 + self.low_main_fb.dcC1DCDistributionPanelCircuitBreaker = 0x5A self.low_main_fb.reservedCircuitBreaker1 = 0x55 self.low_main_fb.reservedCircuitBreaker2 = 0x55 - self.low_main_fb.emergencyLithiumBatteryGroup2CircuitBreaker = 0x55 + self.low_main_fb.emergencyLithiumBatteryGroup2CircuitBreaker = 0x5A self.low_main_fb.instrumentPowerFailureSignal = 0x55 self.low_main_fb.emergencyPowerFailureSignal = 0x55 self.low_main_fb.instrumentBusbarInsulationLow = 0x55 self.low_main_fb.instrumentBusbarVoltage = 48 self.low_main_fb.bowLowVoltageDistributionBoxCurrent = 10 self.low_main_fb.dcC1InstrumentDC48VCurrent = 5 - self.low_main_fb.reservedCurrent1 = 0 - self.low_main_fb.emergencyLithiumBatteryGroup2Current = 0 + self.low_main_fb.reservedCurrent1 = 110 + self.low_main_fb.emergencyLithiumBatteryGroup2Current = 100 self.low_main_fb.lithiumBatteryGroupInstrumentCurrent = 20 self.low_main_fb.unit4InstrumentDC48VCurrent = 5 - self.low_main_fb.reservedCurrent2 = 0 + self.low_main_fb.reservedCurrent2 = 100 self.low_main_fb.emergency2BusbarVoltage = 48 self.low_main_fb.compositeEnergyManagementSystemEmergencyDC48VCurrent = 2 self.low_main_fb.fuelCellSecuritySystemEmergencyDC48VCurrent = 2 self.low_main_fb.plcControlPowerCurrent = 1 # 仪表汇流排反馈数据 - 测试所有成员 - self.low_bus_fb.unit1CircuitBreaker = 1 - self.low_bus_fb.unit2CircuitBreaker = 1 - self.low_bus_fb.unit3CircuitBreaker = 1 - self.low_bus_fb.unit5CircuitBreaker = 1 - self.low_bus_fb.bowPZDeviceCircuitBreaker = 1 - self.low_bus_fb.reservedCircuitBreaker1 = 0 - self.low_bus_fb.reservedCircuitBreaker2 = 0 - self.low_bus_fb.emergencyLithiumBatteryGroup1CircuitBreaker = 0 - self.low_bus_fb.powerFailureSignal = 0 - self.low_bus_fb.waterIngressionAlarm = 0 + self.low_bus_fb.unit1CircuitBreaker = 0x55 + self.low_bus_fb.unit2CircuitBreaker = 0x55 + self.low_bus_fb.unit3CircuitBreaker = 0x55 + self.low_bus_fb.unit5CircuitBreaker = 0x55 + self.low_bus_fb.bowPZDeviceCircuitBreaker = 0x55 + self.low_bus_fb.reservedCircuitBreaker1 = 0x55 + self.low_bus_fb.reservedCircuitBreaker2 = 0x55 + self.low_bus_fb.emergencyLithiumBatteryGroup1CircuitBreaker = 0x55 + self.low_bus_fb.instrumentPowerFailureSignal = 0x5A + self.low_bus_fb.emergencyPowerFailureSignal = 0x5A + self.low_bus_fb.waterIngressionAlarm = 0x55 self.low_bus_fb.instrumentBusbarVoltage = 48 self.low_bus_fb.instrumentBusbarCurrent = 500 self.low_bus_fb.unit1Current = 100 @@ -131,7 +132,7 @@ class PowerManagerSimulator: self.low_bus_fb.unit3Current = 100 self.low_bus_fb.unit5Current = 100 self.low_bus_fb.bowPZDeviceCurrent = 50 - self.low_bus_fb.emergencyLithiumBatteryGroup1Current = 0 + self.low_bus_fb.emergencyLithiumBatteryGroup1Current = 100 self.low_bus_fb.emergency1BusbarVoltage = 48 def start(self): diff --git a/test/disSysTest/udpMsg.py b/test/disSysTest/udpMsg.py index 24097de..d2a44c2 100644 --- a/test/disSysTest/udpMsg.py +++ b/test/disSysTest/udpMsg.py @@ -366,7 +366,7 @@ class msg_disLowBusFbMsg: self.start1 = 0x40 self.start2 = 0x40 self.id = 0x0008 - self.length = 24 # disLowBusState结构体大小 + self.length = 25 # disLowBusState结构体大小 self.checkCode = 0x00 # disLowBusState成员 @@ -378,7 +378,8 @@ class msg_disLowBusFbMsg: self.reservedCircuitBreaker1 = 0x00 self.reservedCircuitBreaker2 = 0x00 self.emergencyLithiumBatteryGroup1CircuitBreaker = 0x00 - self.powerFailureSignal = 0x00 + self.instrumentPowerFailureSignal = 0x00 + self.emergencyPowerFailureSignal = 0x00 self.waterIngressionAlarm = 0x00 self.instrumentBusbarVoltage = 0 self.instrumentBusbarCurrent = 0 @@ -406,7 +407,8 @@ class msg_disLowBusFbMsg: data += struct.pack('