//======================================================================= // SystemDataTest: SystemData 的故障检测逻辑(断路器映射、绝缘、电源失电、 // 漏水、DCDC、继电器位提取、缩放、故障码集合、漏水位)。 // 不改动生产代码;仅链接现有 systemData.h + SQLite + MOOS。 //======================================================================= #include #include "MOOS/libMOOS/Utils/MOOSUtilityFunctions.h" // MOOSTime (updateCommonStatus) #include "systemData.h" #include "faultCode.h" TEST(SystemDataTest, BreakerMapping) { SystemData sd; unsigned char status = 0; // 0x55 = 闭合(1),无故障码 sd.updateBreakerFault(status, 0x55, 99); EXPECT_EQ(status, 1u); EXPECT_EQ(sd.disSysFaultCode.count(99), 0u); // 0xAA = 断开(0),无故障码 sd.updateBreakerFault(status, 0xAA, 99); EXPECT_EQ(status, 0u); EXPECT_EQ(sd.disSysFaultCode.count(99), 0u); // 0x5A = 故障脱扣(2),插入故障码 sd.updateBreakerFault(status, 0x5A, 99); EXPECT_EQ(status, 2u); EXPECT_EQ(sd.disSysFaultCode.count(99), 1u); // 再次正常后擦除 sd.updateBreakerFault(status, 0x55, 99); EXPECT_EQ(sd.disSysFaultCode.count(99), 0u); } TEST(SystemDataTest, HighVolBusFaultDetection) { SystemData sd; disHighVolBusState s{}; // 全 0xAA(断开,正常) s.fuelCellCircuitBreaker = 0xAA; s.powerLithiumBatteryCircuitBreaker = 0xAA; s.propulsionMotorCircuitBreaker = 0xAA; s.lithiumBatteryGroupInstrumentCircuitBreaker = 0xAA; s.dcDc5ModuleCircuitBreaker = 0xAA; s.bowHighVoltageDistributionBoxCircuitBreaker = 0xAA; s.sternFTDevice45CircuitBreaker = 0xAA; s.sternRudderSwitch1CircuitBreaker = 0xAA; s.sternRudderSwitch2CircuitBreaker = 0xAA; s.powerBusInsulationStatus = 0x55; s.aBusInsulationStatus = 0x55; s.meterPowerLossSignal = 0x55; s.emergencyPowerLossSignal = 0x55; sd.updateSystemData(s); EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 0u); EXPECT_EQ(sd.disSysFaultCode.count(1), 0u); // 燃料电断路器故障脱扣 s.fuelCellCircuitBreaker = 0x5A; sd.updateSystemData(s); EXPECT_EQ(sd.power_bus_status.fuelCellCircuitBreaker, 2u); EXPECT_EQ(sd.disSysFaultCode.count(1), 1u); // 动力锂电池闭合 + A汇流排/动力母排绝缘低 → 34/35 s.fuelCellCircuitBreaker = 0xAA; s.powerLithiumBatteryCircuitBreaker = 0x55; s.powerBusInsulationStatus = 0xAA; s.aBusInsulationStatus = 0xAA; sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(34), 1u); EXPECT_EQ(sd.disSysFaultCode.count(35), 1u); EXPECT_EQ(sd.power_bus_status.powerBusInsulationStatus, 1u); EXPECT_EQ(sd.power_bus_status.aBusInsulationStatus, 1u); // 电源失电 → 36/37 s.meterPowerLossSignal = 0xAA; s.emergencyPowerLossSignal = 0xAA; sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(36), 1u); EXPECT_EQ(sd.disSysFaultCode.count(37), 1u); // 全部恢复正常后故障码擦除 s.powerLithiumBatteryCircuitBreaker = 0xAA; s.powerBusInsulationStatus = 0x55; s.aBusInsulationStatus = 0x55; s.meterPowerLossSignal = 0x55; s.emergencyPowerLossSignal = 0x55; sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(34), 0u); EXPECT_EQ(sd.disSysFaultCode.count(35), 0u); EXPECT_EQ(sd.disSysFaultCode.count(36), 0u); EXPECT_EQ(sd.disSysFaultCode.count(37), 0u); } TEST(SystemDataTest, HighAVolBusFaultDetection) { SystemData sd; disHighAVolBusState s{}; s.actuatorCircuitBreaker = 0x5A; // 启闭机构断路器脱扣 → 14 s.xczCircuitBreaker = 0x55; s.instrumentPowerFailureSignal = 0x55; s.emergencyPowerFailureSignal = 0x55; s.waterIngressionAlarm = 0x55; sd.updateSystemData(s); EXPECT_EQ(sd.power_a_bus_status.actuatorCircuitBreaker, 2u); EXPECT_EQ(sd.disSysFaultCode.count(14), 1u); s.actuatorCircuitBreaker = 0xAA; s.instrumentPowerFailureSignal = 0xAA; // 失电 → 38 s.emergencyPowerFailureSignal = 0xAA; // 失电 → 39 s.waterIngressionAlarm = 0xAA; // 浸水 → leakStatus[BOW_HIGH_VOLTAGE] sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(14), 0u); EXPECT_EQ(sd.disSysFaultCode.count(38), 1u); EXPECT_EQ(sd.disSysFaultCode.count(39), 1u); EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_HIGH_VOLTAGE]); } TEST(SystemDataTest, LowMainBusFaultDetection) { SystemData sd; disLowMainBusState s{}; s.lithiumBatteryGroupInstrumentCircuitBreaker = 0x5A; // 19 s.unit4InstrumentDC48VCircuitBreaker = 0x5A; // 21 s.instrumentPowerFailureSignal = 0xAA; // 41 s.emergencyPowerFailureSignal = 0xAA; // 42 s.instrumentBusbarInsulationLow = 0xAA; // 43 sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(19), 1u); EXPECT_EQ(sd.disSysFaultCode.count(21), 1u); EXPECT_EQ(sd.disSysFaultCode.count(41), 1u); EXPECT_EQ(sd.disSysFaultCode.count(42), 1u); EXPECT_EQ(sd.disSysFaultCode.count(43), 1u); } TEST(SystemDataTest, LowBusFaultDetection) { SystemData sd; disLowBusState s{}; s.unit1CircuitBreaker = 0x5A; // 26 s.emergencyLithiumBatteryGroup1CircuitBreaker = 0x5A; // 33 s.powerFailureSignal = 0xAA; // 44 s.emergencyPowerFailureSignal = 0xAA; // 45 s.waterIngressionAlarm = 0xAA; // leakage BOW_LOW_VOLTAGE sd.updateSystemData(s); EXPECT_EQ(sd.disSysFaultCode.count(26), 1u); EXPECT_EQ(sd.disSysFaultCode.count(33), 1u); EXPECT_EQ(sd.disSysFaultCode.count(44), 1u); EXPECT_EQ(sd.disSysFaultCode.count(45), 1u); EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_BOW_LOW_VOLTAGE]); } TEST(SystemDataTest, CcuStateScalingAndRelayBits) { SystemData sd; ccuState c{}; c.ins_soc = 60; c.dyn_soc = 80; c.ins_relay_status1 = 0x12; // 高4位=1(充电), 低4位=2(正极) c.ins_relay_status2 = 0x34; c.ins_voltage_link = 4800; // ×0.1 = 480.0 c.ins_water_leak_dcdc_status = 0x11; // 高4位=1 漏水, 低4位=1 DCDC故障 c.dyn_water_leak_status = 0x21; // 高4位=2, 低4位=1 sd.updateSystemData(c); EXPECT_EQ(sd.ins_soc, 60); EXPECT_EQ(sd.dyn_soc, 80); EXPECT_EQ(sd.ins_pos_relay_status, 2u); // 低4位 EXPECT_EQ(sd.ins_charge_relay_status, 1u); // 高4位 EXPECT_EQ(sd.ins_precharge_relay_status, 4u); // 低4位 of status2 EXPECT_EQ(sd.ins_neg_relay_status, 3u); // 高4位 of status2 EXPECT_NEAR(sd.ins_voltage_link, 480.0, 0.01); EXPECT_EQ(sd.water_leak_status_from_insbat, 1u); EXPECT_EQ(sd.dcdc_status_from_insbat, 1u); EXPECT_TRUE(sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY]); } TEST(SystemDataTest, FaultCodeSetAndLevel) { SystemData sd; EXPECT_EQ(sd.getFaultCodeLevel(), 0u); sd.insertFaultCode(0x1102); // 0x11>>... level = (0x1102>>8)&0xF = 1 EXPECT_EQ(sd.getFaultCodeLevel(), 1u); sd.insertFaultCode(0x4402); // level = (0x4402>>8)&0xF = 4 EXPECT_EQ(sd.getFaultCodeLevel(), 4u); sd.eraseFaultCode(0x4402); EXPECT_EQ(sd.getFaultCodeLevel(), 1u); auto codes = sd.getFaultCode(); EXPECT_EQ(codes.count(0x1102), 1u); } TEST(SystemDataTest, LeakageCodeGeneration) { SystemData sd; EXPECT_EQ(sd.generateLeakageCode(), 0u); sd.leakStatus[SystemData::LEAKAGE_BOW_EMERGENCY] = true; // 0x01 sd.leakStatus[SystemData::LEAKAGE_FUEL_CELL] = true; // 0x08 sd.leakStatus[SystemData::LEAKAGE_LI_BATTERY] = true; // 0x10 EXPECT_EQ(sd.generateLeakageCode(), 0x19u); } TEST(SystemDataTest, CommonStatusTimeout) { SystemData sd; sd.updateCommonStatus(30.0); // 新建 SystemData 的 lastUpdateTime=0,与当前 MOOSTime 之差远大于 30s EXPECT_TRUE(sd.device_common_status.ccu_status.isTimeout); }